react-native-image-picker - 重建后的持久存储
react-native-image-picker - persistent storage after rebuild
我已经在屏幕上撞了一段时间了,尽管我在 git 或 Whosebug 上找到了所有信息,但还是无法正常工作。
我想要实现的目标:
所选图像(来自库或相机)的持久性。当我重建我的应用程序时也会持久化,这意味着当我 运行 react-native run-ios
for iOS 或 react-native run-android
for Android.
我实现了什么
这是我添加图像时调用的函数。
ImagePicker.showImagePicker({
storageOptions: {
path: 'myCustomPath',
waitUntilSaved: true,
cameraRoll: true,
skipBackup : true
},
noData: true
}, res => {
if (res.didCancel) {
console.log("User cancelled");
} else if (res.error) {
console.log("Error", res.error);
} else {
console.log("Picker Response:", res);
// Getting the fileName as for iOS the fileName is incorrect even with waitUntilSaved to true.
const path = res.uri.split("/");
const fileName = path[path.length-1];
let uri = "file://" + Platform.select({
android: RNFS.ExternalStorageDirectoryPath + "/Pictures/",
ios: RNFS.DocumentDirectoryPath+"/"
})
+ "myCustomPath/" + fileName
this.setState({
pickedImage: {
uri: uri,
}
});
this.props.onImagePicked({ uri: res.uri });
}
});
在我的主页上,我显示 <Thumbnail square style={{width:50, height:50}} source={info.item.image} />
中的图像
---- 编辑开始 -----
---- 解决方案 ----
解决方案是使用文件名重建我想要显示图像的路径:
<Thumbnail square style={{width:50, height:50}} source={{uri : RNFS.DocumentDirectoryPath+"/"+info.item.image.fileName}} />
---- 编辑结束 -----
结果
这是结果,您会看到在 Android 上效果很好,但在 iOS 上效果不佳。
我使用 react-native-image-picker
.
在库中选择了一张图片
Android
"Picker Response":
fileName: "image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"
fileSize: 235728
height: 1440
isVertical: true
originalRotation: 0
path: "/storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"
type: "image/jpeg"
uri: "file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"
width: 1080
我的图像的保存 "uri" 是:file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg
行为如下:
- 左图是保存图片后的截图,
- 右边的截图是重建后,打开应用程序,我的图像仍然可见!
--> 开心!
现在iOS
"Picker Response" :
fileName: "IMG_0004.JPG"
fileSize: 470300
height: 1618
isVertical: true
latitude: 64.752895
longitude: -14.538611666666666
origURL: "assets-library://asset/asset.JPG?id=99D53A1F-FEEF-40E1-8BB3-7DD55A43C8B7&ext=JPG"
timestamp: "2012-08-08T21:29:49Z"
type: "image/jpeg"
uri: "file:///Users/[name]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/4756F0A2-9CCC-4F9A-9315-D55434328FD9/Documents/myCustomPath/6A5C27E3-89F7-465F-A855-66749C92D086.jpg"
width: 1080
我的图像的保存 "uri" 是:file:///Users/[name]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/4756F0A2-9CCC-4F9A-9315-D55434328FD9/Documents/myCustomPath/6A5C27E3-89F7-465F-A855-66749C92D086.jpg
行为如下:
- 左图是保存图片后的截图,
- 右边的截图是重建后,打开应用程序,我的图像仍然可见!
--> 不开心!
我的问题
我已经阅读了所有关于返回的 uri 的临时方面的内容,看看 react-native-image-picker
是怎么说的:
On iOS, don't assume that the absolute uri returned will persist.
我也发现这个 有类似的问题,但是 none 有效:
RNFS.DocumentDirectoryPath
重建后路径中有不同的 UUID,因此找不到文件,因为它是用以前的 UUID 保存的
- 我尝试将 uri 保存为 iOS,因为 '~/Documents/myCustomPath/myfilename.jpg' 具有相同的行为。添加时显示,重建后空白。
重建前我有:
文档目录路径为:
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/
和我保存的图片 uri :
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/myCustomPath/20969988-633B-46BD-8558-E39C3ADD6D12.jpg
但在重建后,应用程序 UUID 更改为 BEE128C8-5FCF-483C-A829-8F7A0BB4E966
,现在我的文档目录为
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Bundle/Application/BEE128C8-5FCF-483C-A829-8F7A0BB4E966/Documents
但仍在查看 uri 中的图片:
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/myCustomPath/20969988-633B-46BD-8558-E39C3ADD6D12.jpg
当图片现在实际位于:
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/BEE128C8-5FCF-483C-A829-8F7A0BB4E966/Documents/myCustomPath/20969988-633B-46BD-8558-E39C3ADD6D12.jpg
因此,由于 iOS.
上的路径是动态的,我该如何应对重建后 App UUID 的变化
我使用的版本:
- "react-native": "0.57.8",
- "react-native-fs": "^2.13.2",
- "react-native-image-picker": "^0.28.0"
如react-native-image-picker
所述
On iOS, don't assume that the absolute uri returned will persist.
这意味着如果您将绝对 uri 存储到文件然后执行 react-native run-ios
应用程序 GUID 将更改并且绝对 uri 将不再存在或工作。然而,这 重要 图像将在您保存它的文件夹中,因为它被复制了。
解决这个问题的唯一方法是保存文件的目录和文件名,并在需要时重建 uri。
所以这意味着您将保存状态
this.setState({ image: '/myCustomPath/image.jpg' });
然后你要用它的时候你会像这样重建路径
let pathToFile = `${RNFS.DocumentDirectoryPath}${this.state.image}`
您可以通过将“/Documents/...”之前的路径替换为波浪号“~”来简单地解决这个问题(不依赖 react-native-fs)。
let pathToFile = "file:///var/mobile/Containers/Data/Application/9793A9C3-C666-4A0E-B630-C94F02E32BE4/Documents/images/72706B9A-12DF-4196-A3BE-6F17C61CAD06.jpg"
if (Platform.OS === 'ios') {
pathToFile = '~' + pathToFile.substring(pathToFile.indexOf('/Documents'));
}
正如您在他们的 source code.
中所见,React Native 支持此功能
我已经在屏幕上撞了一段时间了,尽管我在 git 或 Whosebug 上找到了所有信息,但还是无法正常工作。
我想要实现的目标:
所选图像(来自库或相机)的持久性。当我重建我的应用程序时也会持久化,这意味着当我 运行 react-native run-ios
for iOS 或 react-native run-android
for Android.
我实现了什么
这是我添加图像时调用的函数。
ImagePicker.showImagePicker({
storageOptions: {
path: 'myCustomPath',
waitUntilSaved: true,
cameraRoll: true,
skipBackup : true
},
noData: true
}, res => {
if (res.didCancel) {
console.log("User cancelled");
} else if (res.error) {
console.log("Error", res.error);
} else {
console.log("Picker Response:", res);
// Getting the fileName as for iOS the fileName is incorrect even with waitUntilSaved to true.
const path = res.uri.split("/");
const fileName = path[path.length-1];
let uri = "file://" + Platform.select({
android: RNFS.ExternalStorageDirectoryPath + "/Pictures/",
ios: RNFS.DocumentDirectoryPath+"/"
})
+ "myCustomPath/" + fileName
this.setState({
pickedImage: {
uri: uri,
}
});
this.props.onImagePicked({ uri: res.uri });
}
});
在我的主页上,我显示 <Thumbnail square style={{width:50, height:50}} source={info.item.image} />
---- 编辑开始 ----- ---- 解决方案 ----
解决方案是使用文件名重建我想要显示图像的路径:
<Thumbnail square style={{width:50, height:50}} source={{uri : RNFS.DocumentDirectoryPath+"/"+info.item.image.fileName}} />
---- 编辑结束 -----
结果
这是结果,您会看到在 Android 上效果很好,但在 iOS 上效果不佳。
我使用 react-native-image-picker
.
Android
"Picker Response":
fileName: "image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"
fileSize: 235728
height: 1440
isVertical: true
originalRotation: 0
path: "/storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"
type: "image/jpeg"
uri: "file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"
width: 1080
我的图像的保存 "uri" 是:file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg
行为如下:
- 左图是保存图片后的截图,
- 右边的截图是重建后,打开应用程序,我的图像仍然可见!
--> 开心!
现在iOS
"Picker Response" :
fileName: "IMG_0004.JPG"
fileSize: 470300
height: 1618
isVertical: true
latitude: 64.752895
longitude: -14.538611666666666
origURL: "assets-library://asset/asset.JPG?id=99D53A1F-FEEF-40E1-8BB3-7DD55A43C8B7&ext=JPG"
timestamp: "2012-08-08T21:29:49Z"
type: "image/jpeg"
uri: "file:///Users/[name]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/4756F0A2-9CCC-4F9A-9315-D55434328FD9/Documents/myCustomPath/6A5C27E3-89F7-465F-A855-66749C92D086.jpg"
width: 1080
我的图像的保存 "uri" 是:file:///Users/[name]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/4756F0A2-9CCC-4F9A-9315-D55434328FD9/Documents/myCustomPath/6A5C27E3-89F7-465F-A855-66749C92D086.jpg
行为如下:
- 左图是保存图片后的截图,
- 右边的截图是重建后,打开应用程序,我的图像仍然可见!
--> 不开心!
我的问题
我已经阅读了所有关于返回的 uri 的临时方面的内容,看看 react-native-image-picker
是怎么说的:
On iOS, don't assume that the absolute uri returned will persist.
我也发现这个
RNFS.DocumentDirectoryPath
重建后路径中有不同的 UUID,因此找不到文件,因为它是用以前的 UUID 保存的- 我尝试将 uri 保存为 iOS,因为 '~/Documents/myCustomPath/myfilename.jpg' 具有相同的行为。添加时显示,重建后空白。
重建前我有:
文档目录路径为:
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/
和我保存的图片 uri :
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/myCustomPath/20969988-633B-46BD-8558-E39C3ADD6D12.jpg
但在重建后,应用程序 UUID 更改为 BEE128C8-5FCF-483C-A829-8F7A0BB4E966
,现在我的文档目录为
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Bundle/Application/BEE128C8-5FCF-483C-A829-8F7A0BB4E966/Documents
但仍在查看 uri 中的图片:
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/myCustomPath/20969988-633B-46BD-8558-E39C3ADD6D12.jpg
当图片现在实际位于:
file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/BEE128C8-5FCF-483C-A829-8F7A0BB4E966/Documents/myCustomPath/20969988-633B-46BD-8558-E39C3ADD6D12.jpg
因此,由于 iOS.
上的路径是动态的,我该如何应对重建后 App UUID 的变化我使用的版本:
- "react-native": "0.57.8",
- "react-native-fs": "^2.13.2",
- "react-native-image-picker": "^0.28.0"
如react-native-image-picker
所述
On iOS, don't assume that the absolute uri returned will persist.
这意味着如果您将绝对 uri 存储到文件然后执行 react-native run-ios
应用程序 GUID 将更改并且绝对 uri 将不再存在或工作。然而,这 重要 图像将在您保存它的文件夹中,因为它被复制了。
解决这个问题的唯一方法是保存文件的目录和文件名,并在需要时重建 uri。
所以这意味着您将保存状态
this.setState({ image: '/myCustomPath/image.jpg' });
然后你要用它的时候你会像这样重建路径
let pathToFile = `${RNFS.DocumentDirectoryPath}${this.state.image}`
您可以通过将“/Documents/...”之前的路径替换为波浪号“~”来简单地解决这个问题(不依赖 react-native-fs)。
let pathToFile = "file:///var/mobile/Containers/Data/Application/9793A9C3-C666-4A0E-B630-C94F02E32BE4/Documents/images/72706B9A-12DF-4196-A3BE-6F17C61CAD06.jpg"
if (Platform.OS === 'ios') {
pathToFile = '~' + pathToFile.substring(pathToFile.indexOf('/Documents'));
}
正如您在他们的 source code.
中所见,React Native 支持此功能