rn中对于安卓与ios下载远程图片的处理


安装环境

使用包

1
2
import RNFS from 'react-native-fs';
import CameraRoll from '@react-native-community/cameraroll';

安装

1
2
npm install react-native-fs --save
npm install @react-native-community/cameraroll --save

其中 CameraRoll 用来将图片存储到手机相册,使用了 save() 方法

1
save(tag, {type, album})

IOS

1
2
3
4
5
6
7
CameraRoll.save('网络图片url', 'photo')
.then(() => {
Alert.alert('保存成功!');
})
.catch(function (error) {
Alert.alert('保存失败!');
});

Android

由于安卓上处理图片时,tag只能为本地图片,若为远程图片会被截掉域名导致获取不到图片,对比如下

1
2
ios:https://blog.uimentama.com/blogfile/uiavatar.jpg
Android:/blogfile/uiavatar.jpg

因此需要使用react-native-fs来将远程图片临时下载至本地缓存,再通过cameraroll下载缓存中的文件至本地,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 获取后缀名
const suffix = imgUrl.substring('网络图片url'.lastIndexOf('.'));
// 获取存储路径(存放路径+自定义文件名+后缀名)
// ExternalCachesDirectoryPath(String)外部缓存目录的绝对路径(仅适用于Android)
const downloadDest = `${RNFS.ExternalCachesDirectoryPath}/marrydream_${
new Date().getTime() + suffix
}`;
RNFS.downloadFile({
fromUrl: imgUrl,
toFile: downloadDest,
})
.promise.then((res) => {
// 调用cameraRoll,与ios不同的是tag变为缓存图片的url
CameraRoll.save(downloadDest, 'photo')
.then(() => {
Alert.alert('保存成功!');
})
.catch(function (error) {
Alert.alert('保存失败!');
});
})
.catch((err) => {
Alert.alert('保存失败!');
});

同时兼容ios与Android

只需通过判断系统,分别对cameraRoll使用不同的tag即可,若为安卓则添加 fs 处理操作,ios 则直接使用
整体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import RNFS from 'react-native-fs';
import CameraRoll from '@react-native-community/cameraroll';
import {Alert, Platform} from 'react-native';
import {getLibraryPermission} from '@/utils/permissions';

const CameraRollSave = (imgUrl, callback = () => {}) => {
CameraRoll.save(imgUrl, 'photo')
.then(() => {
callback();
Alert.alert('保存成功!');
})
.catch(function (error) {
Alert.alert('保存失败!');
});
};

export default function saveImage(imgUrl, callback = () => {}) {
const suffix = imgUrl.substring(imgUrl.lastIndexOf('.'));
// 这里使用自己封装的方法事先判断了一下有无存储权限
getLibraryPermission().then(() => {
if (Platform.OS === 'ios') {
return CameraRollSave(imgUrl);
}
const downloadDest = `${RNFS.ExternalCachesDirectoryPath}/marrydream_${
new Date().getTime() + suffix
}`;
RNFS.downloadFile({
fromUrl: imgUrl,
toFile: downloadDest,
})
.promise.then((res) => {
CameraRollSave(downloadDest, callback);
})
.catch((err) => {
Alert.alert('保存失败!');
});
});
}