Сохранение фотографий и видео на устройство 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