react-native-image-picker - 重建后的持久存储 [英] react-native-image-picker - persistent storage after rebuild

查看:34
本文介绍了react-native-image-picker - 重建后的持久存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的头一直在屏幕上打了一段时间,尽管我在 git 或 stackoverflow 上找到了所有信息,但还是无法让它工作.

我正在努力实现的目标:

所选图像的持久性(来自库或相机).当我重建我的应用程序时也保持持久性,这意味着当我为 iOS 运行 react-native run-ios 或为 Android 运行 react-native run-android 时.

我已经实施的

这是我添加图像时调用的函数.

ImagePicker.showImagePicker({存储选项:{路径:'我的自定义路径',等待直到保存:真,相机卷:真的,跳过备份:真},无数据:真实}, res =>{如果(res.didCancel){console.log("用户已取消");} else if (res.error) {console.log("错误", res.error);} 别的 {console.log("选择器响应:", res);//获取文件名,对于 iOS,即使 waitUntilSaved 为 true,文件名也是不正确的.const path = res.uri.split("/");const fileName = path[path.length-1];让 uri = "file://" + Platform.select({android: RNFS.ExternalStorageDirectoryPath + "/图片/",ios: RNFS.DocumentDirectoryPath+"/"})+ "myCustomPath/" + 文件名this.setState({选择图像:{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 在库中选择了一个图像.

安卓

选择器响应":

fileName: "image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"文件大小:235728高度:1440isVertical: 真原始旋转:0路径:/storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"类型:图像/jpeg"uri: "file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg"宽度:1080

我的图像的保存uri"是:file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg>

行为如下:

  • 左边的截图是保存我的图片后,
  • 右图是重建后的截图,打开应用,我仍然看到我的图像!

--> 快乐!

现在在 iOS 上

选择器响应":

文件名:IMG_0004.JPG"文件大小:470300身高:1618isVertical: 真纬度:64.752895经度:-14.538611666666666origURL: "assets-library://asset/asset.JPG?id=99D53A1F-FEEF-40E1-8BB3-7DD55A43C8B7&ext=JPG"时间戳:2012-08-08T21:29:49Z"类型:图像/jpeg"uri: "file:///Users/[name]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/4756F0A2-9CCC-4F9A-931934D558FD文件/myCustomPath/6A5C27E3-89F7-465F-A855-66749C92D086.jpg"宽度: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 是怎么说的:

<块引用>

在 iOS 上,不要假设返回的绝对 uri 会持续存在.

我还发现了这个 线程 有类似的问题,但没有一个工作:

  • RNFS.DocumentDirectoryPath 重建后的路径中具有不同的 UUID,因此未找到该文件,因为它是使用先前的 UUID 保存的
  • 我尝试为 iOS 保存 uri,因为 '~/Documents/myCustomPath/myfilename.jpg' 具有相同的行为.添加时显示,重建后空白.

我在重建之前:

文档目录路径为:file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F8038文档/

和我保存的图片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-A82-8F7A0BB4E966/文档

但仍在查看 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 上是动态的,我该如何应对重建后应用 UUID 的变化.

我使用的版本:

  • "react-native": "0.57.8",
  • "react-native-fs": "^2.13.2",
  • "react-native-image-picker": "^0.28.0"

解决方案

正如 react-native-image-picker 所述

<块引用>

在 iOS 上,不要假设返回的绝对 uri 会持续存在.

这意味着,如果您将绝对 uri 存储到文件中,然后执行 react-native run-ios 应用程序 GUID 将更改并且绝对 uri 将不再存在或工作.但是,这是重要图像将在您保存它的文件夹中,因为它被复制.

解决此问题的唯一解决方案是保存文件的目录和文件名,并在您想使用它时重新构建 uri.

所以这意味着您将保存状态

this.setState({ image: '/myCustomPath/image.jpg' });

然后当你使用它时你会像这样重建路径

let pathToFile = `${RNFS.DocumentDirectoryPath}${this.state.image}`

I've been hitting my head on the screen for some time and just can't get it to work despite all the information I've found on git or stackoverflow.

What I'm trying to achieve:

Persistence of the images selected (from library or camera). Persistence also when I rebuild my app, which means when I run react-native run-ios for iOS, or react-native run-android for Android.

What I've implemented

Here is my function that is called when I add an image.

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 }); 
   }
});

And in my home page, I display the image in <Thumbnail square style={{width:50, height:50}} source={info.item.image} />

---- EDIT START ----- ---- SOLUTION ----

The solution was to reconstruct the path where I want to display the image using the fileName: <Thumbnail square style={{width:50, height:50}} source={{uri : RNFS.DocumentDirectoryPath+"/"+info.item.image.fileName}} />

---- EDIT ENDS -----

The Result

So here are the results, you'll see works well on Android, but not on iOS. I selected an image on the library using the 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

the save "uri" for my image is : file:///storage/emulated/0/Pictures/myCustomPath/image-d53839d1-fa89-4a61-b648-f74dace53f83.jpg

Behavior is as below :

  • left screenshot is after saving my image,
  • right screenshot is after a rebuild, opening the app, I still see my image!

--> Happy!

Now on 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

the save "uri" for my image is : 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

Behavior is as below :

  • left screenshot is after saving my image,
  • right screenshot is after a rebuild, opening the app, I still see my image!

--> NOT HAPPY!

My issue

I've read all about the temporary aspect of the returned uri and see what react-native-image-picker says about it:

On iOS, don't assume that the absolute uri returned will persist.

I've found also this thread which had a similar issue, but none worked:

  • RNFS.DocumentDirectoryPath after a rebuild had a different UUID in the path, so the file was not found as it was saved with the previous UUID
  • I tried saving for iOS the uri as '~/Documents/myCustomPath/myfilename.jpg' had the same behavior. Displayed when added, blank after rebuild.

I had before the rebuild:

Document directory path being : file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Data/Application/466CAF1A-AF8D-423C-9BF6-F0A242AF8038/Documents/

and my saved picture 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

but after the rebuild the Application UUID changed to BEE128C8-5FCF-483C-A829-8F7A0BB4E966 making now my document directory to be

file:///Users/[user]/Library/Developer/CoreSimulator/Devices/33076AD2-C989-47E9-A803-3E56CC4B09D6/data/Containers/Bundle/Application/BEE128C8-5FCF-483C-A829-8F7A0BB4E966/Documents

but still looking the picture in the 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

When the image is actually now located under:

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

So how can I cope for that App UUID change after a rebuild as paths are dynamic on iOS.

Versions I use:

  • "react-native": "0.57.8",
  • "react-native-fs": "^2.13.2",
  • "react-native-image-picker": "^0.28.0"

解决方案

As react-native-image-picker states

On iOS, don't assume that the absolute uri returned will persist.

This means that if you store the absolute uri to the file and then do react-native run-ios the application GUID will change and that absolute uri will no longer exist or work. However, and this is important the image will be in the folder that you saved it in, as it is copied across.

The only solution to fixing this is to save the directory and the filename of the file and reconstruct the uri when you want to use it.

So that means that you would save in state

this.setState({ image: '/myCustomPath/image.jpg' });

Then when you come to use it you would rebuild the path like this

let pathToFile = `${RNFS.DocumentDirectoryPath}${this.state.image}`

这篇关于react-native-image-picker - 重建后的持久存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆