React Native — сохранение фотографий и видео в галерею устройства

    Сохранение фотографий и видео на устройство android/ios вызывает у многих разработчиков React Native сложность. В этой статье я покажу как можно легко и безболезненно сохранять фотографии по url на устройство.

    Для начала нам понадобятся две библиотеки:

    1. @react-native-community/cameraroll — обеспечивает доступ к галерее(у меня получилось только с версией 1.4.0. На версиях «посвежее» были общеизвестные ошибки, напишите если у вас получилось с другой версией)
    2. rn-fetch-blob — доступ к локальным файлам приложения. Стоить отметить, что данная библиотека работает с react native версии 0.60 и выше


    IOS


    На ios все оказалось очень просто:

    1. Добавляем в Info.plist
    <key>NSCameraUsageDescription</key>
    <string></string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string></string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string></string>
    

    2. Реализация
    import CameraRoll from '@react-native-community/cameraroll';
    
    const saveImageInDevice = async (url) => {
        await CameraRoll.saveToCameraRoll(url, 'photo');
    }
    

    Вот и все! Функция saveImageInDevice принимает на вход адрес ссылки. CameraRoll.saveToCameraRoll загружает файл и сохраняет в галерею устройства. Второй параметр метода saveToCameraRoll может быть так же «video»

    Android


    На устройствах под android немного посложнее. Дело в том, что на android метод saveToCameraRoll не умеет работать с внешним url. Нам нужно сначала загрузить файл во внешнее хранилище, а дальше уже в галерею:

    import {PermissionsAndroid} from 'react-native';
    import CameraRoll from '@react-native-community/cameraroll';
    import RNFetchBlob from 'rn-fetch-blob';
    
    // запрашиваем разрешение на запись внешнему хранилищу
    const checkAndroidPermission = async () => {
        const permission = PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;
        await PermissionsAndroid.request(permission);
    };
    
    const saveImageInDevice = async (url) => {
         await checkAndroidPermission();
            let res = await RNFetchBlob
              .config({
                fileCache : true,
                appendExt : 'jpg' 
              })
              .fetch('GET', url);
         url = res.path();
         await CameraRoll.saveToCameraRoll(url, 'photo');
    }
    


    RNFetchBlob.fetch по GET запросу загрузит файл во внешнее хранилище и передаст url этого файла. Далее CameraRoll.saveToCameraRoll загрузит этот файл в галерею.

    На этом все. Спасибо за внимание!

    Ссылки:
    github.com/react-native-community/react-native-cameraroll
    github.com/joltup/rn-fetch-blob
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 4

      +1

      Прошу прощенья, а можно слово "фотоплёнка" заменить на "галерея"? Я фотографирую на плёнку и на некоторое время завис, читая заголовок, пытаясь понять, какая плёнка может быть в устройстве с реактом.

        0
        Заменил. Спасибо!
        0
        // запрашиваем разрешение на запись внешнему хранилищу
        const checkAndroidPermission = async () => {
          try {
            const permission = PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;
            await PermissionsAndroid.request(permission);
            Promise.resolve();
          } catch (error) {
            Promise.reject(error);
          }
        };

        checkAndroidPermission() всегда успешно резолвится, надо либо возвращать Promise, либо убрать try/catch.

          0
          Точно! Спасибо, поправил.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое