wkh237 / react-native-fetch-blob

A project committed to making file access and data transfer easier, efficient for React Native developers.
MIT License
2.61k stars 1.6k forks source link

Support file upload/operations from any RCTURLRequestHandler url? #218

Open adbl opened 7 years ago

adbl commented 7 years ago

Hi! This library supports file upload and copy etc for photos via the old (deprecated) iOS ALAssetLibrary, by matching on the asset-library:// url scheme.

We are starting to integrate https://github.com/olofd/react-native-photos-framework so that our users can upload photos that are stored in iCloud too. That library is integrated with the RCTImageLoader, it has its own url scheme pk://, so it can load images in <Image /> components.

We will also start using the RN ImageEditor (http://facebook.github.io/react-native/releases/0.36/docs/imageeditor.html#imageeditor) for cropping of photos. The cropped photos gets (temporarily) stored in memory by RCTImageStore which is also hooked into RCTImageLoader with it's own url schema.

RCTImageLoader has a method called loadImageWithURLRequest, which takes the photo url, it finds the appropriate ImageLoader and calls back with a UIImage (which have access to the data).

I suggest that all file operations (where applicable)/upload can fallback to using data from RCTImageLoader, with the added benefit that asset-library files also come for free.

One possible issue is that the RCTImageLoader also loads photos from http schemes...?

I will implement some small code that just covers our own needs first (copy a ImageLoader image to temporary file), which we can share here, but I cannot promise to do a proper PR as it looks like it would affect a lot of the code here.

adbl commented 7 years ago

Ok, I misunderstood some things. A UIImage doesn't actually have the "file data", it only has the decoded image data. So you need to convert it to image file data using something like UIImageJPEGRepresentation, this means compressing the image again (if jpeg)...

So ImageLoaders may not be useful from a "file" perspective. But RCTNetworking uses these things called RCTURLRequestHandler's, which also answer to url requests (when calling networkTaskWithRequest). RCTImageStore implements this interface and RCTImageLoader does too checking all the registered RCTImageURLLoader's (like react-native-photos-framework), so it can send any image as data (using UIImageJPEGRepresentation(image, 1.0) ...).

So, the suggestion is instead if react-native-fetch-blob should fall back to using RCTNetworking to get file data. From what I can tell, this can deliver:

And recompressed photo from any other RCTImageURLLoader, such as react-native-photos-framework. If such image loaders also implement the RCTURLRequestHandler then they will deliver the raw file data without recompressing.

A limitation is that none of the built-ins support streaming.

wkh237 commented 7 years ago

@adbl , thanks so much about the detailed information ! 👍 It's great to know more about core API, perhaps we'll use them somewhere 😄 I'm quite busy these days may not have too much time on this project, will have a look on what you've mentioned above when I have time.