|  | @@ -1,14 +1,16 @@
 | 
	
		
			
			| 1 | 1 |  # react-native-fetch-blob [](https://badge.fury.io/js/react-native-fetch-blob) 
 | 
	
		
			
			| 2 | 2 |  
 | 
	
		
			
			| 3 |  | -A react-native module for fetch file/image with custom headers, supports blob response data, and upload/download progress.
 | 
	
		
			
			|  | 3 | +## v0.5.0 Work In Progress README.md
 | 
	
		
			
			| 4 | 4 |  
 | 
	
		
			
			| 5 |  | -If you're dealing with image or file server that requires an `Authorization` token in the header, or you're having problem with `fetch` API when receiving blob data, you might try this module (this is also the reason why I made this).
 | 
	
		
			
			|  | 5 | +A react-native module for upload, and download file with custom headers. Supports blob response data, upload/download progress, and file reader API that enables you process file content in js context (such as display image data, string or image process).
 | 
	
		
			
			| 6 | 6 |  
 | 
	
		
			
			| 7 |  | -See [[fetch] Does fetch with blob() marshal data across the bridge?](https://github.com/facebook/react-native/issues/854).
 | 
	
		
			
			|  | 7 | +If you're dealing with image or file server that requires special field in the header, or you're having problem with `fetch` API when receiving blob data, you might try this module.
 | 
	
		
			
			| 8 | 8 |  
 | 
	
		
			
			| 9 |  | -This module enables you upload/download binary data in js, see [Examples](#user-content-usage) bellow.
 | 
	
		
			
			|  | 9 | +See [[fetch] Does fetch with blob() marshal data across the bridge?](https://github.com/facebook/react-native/issues/854) for the reason why we made this module.
 | 
	
		
			
			| 10 | 10 |  
 | 
	
		
			
			| 11 |  | -The source code is very simple, just an implementation of native HTTP request, supports both Android (uses awesome native library  [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client])) and IOS.
 | 
	
		
			
			|  | 11 | +In latest version (v0.5.0), you can upload/download files directly with file path. We've also introduced `file stream` API for reading **large files** from storage, see [Examples](#user-content-usage) bellow.
 | 
	
		
			
			|  | 12 | +
 | 
	
		
			
			|  | 13 | +This module implements native HTTP request, supports both Android (uses awesome native library  [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client])) and IOS.
 | 
	
		
			
			| 12 | 14 |  
 | 
	
		
			
			| 13 | 15 |  ## Usage
 | 
	
		
			
			| 14 | 16 |  
 | 
	
	
		
			
			|  | @@ -18,6 +20,8 @@ The source code is very simple, just an implementation of native HTTP request, s
 | 
	
		
			
			| 18 | 20 |   * [Upload file](#user-content-upload-example--dropbox-files-upload-api)
 | 
	
		
			
			| 19 | 21 |   * [Multipart/form upload](#user-content-multipartform-data-example--post-form-data-with-file-and-data)
 | 
	
		
			
			| 20 | 22 |   * [Upload/Download progress](#user-content-uploaaddownload-progress)
 | 
	
		
			
			|  | 23 | + * [Deal with files in storage](#user-content-deal-with-files-in-storage)
 | 
	
		
			
			|  | 24 | + * [Release cache files](#user-content-release-cache-files)
 | 
	
		
			
			| 21 | 25 |  * [API](#user-content-api)
 | 
	
		
			
			| 22 | 26 |  
 | 
	
		
			
			| 23 | 27 |  ## Installation
 | 
	
	
		
			
			|  | @@ -63,6 +67,66 @@ RNFetchBlob.fetch('GET', 'http://www.example.com/images/img1.png', {
 | 
	
		
			
			| 63 | 67 |    })
 | 
	
		
			
			| 64 | 68 |  ```
 | 
	
		
			
			| 65 | 69 |  
 | 
	
		
			
			|  | 70 | +#### Download to storage directly
 | 
	
		
			
			|  | 71 | +
 | 
	
		
			
			|  | 72 | +If you want to save the response data directly into file storage rather than convert response data into base64 for some reason.
 | 
	
		
			
			|  | 73 | +
 | 
	
		
			
			|  | 74 | +Put a `config` before calling `fetch`. There're three options which are `path`, `fileCache`, and `appendExt` that let you decide how and where to save the file.
 | 
	
		
			
			|  | 75 | +
 | 
	
		
			
			|  | 76 | +The simplest way is give a `fileCach` option to config, and set it to `true`. This will let the incoming response data stored in a temporary path **wihout** any file extension.
 | 
	
		
			
			|  | 77 | +
 | 
	
		
			
			|  | 78 | +```js
 | 
	
		
			
			|  | 79 | +RNFetchBlob
 | 
	
		
			
			|  | 80 | +  .config({
 | 
	
		
			
			|  | 81 | +    fileCache : true,
 | 
	
		
			
			|  | 82 | +  })
 | 
	
		
			
			|  | 83 | +  .fetch('GET', 'http://www.example.com/file/example.zip', {
 | 
	
		
			
			|  | 84 | +    some headers ..
 | 
	
		
			
			|  | 85 | +  })
 | 
	
		
			
			|  | 86 | +  .then((res) => {
 | 
	
		
			
			|  | 87 | +    // the temp file path
 | 
	
		
			
			|  | 88 | +    console.log('The file saved to ', res.path())
 | 
	
		
			
			|  | 89 | +  })
 | 
	
		
			
			|  | 90 | +```
 | 
	
		
			
			|  | 91 | +
 | 
	
		
			
			|  | 92 | +But in some cases, you might need a file extension even the file is temporary cached. For instance, when use the file path as source of `Image` element the path should end with something like .png or .jpg, you can do this by put one more option in to `config`.
 | 
	
		
			
			|  | 93 | +
 | 
	
		
			
			|  | 94 | +```js
 | 
	
		
			
			|  | 95 | +RNFetchBlob
 | 
	
		
			
			|  | 96 | +  .config({
 | 
	
		
			
			|  | 97 | +    fileCache : true,
 | 
	
		
			
			|  | 98 | +    appendExt : 'png'
 | 
	
		
			
			|  | 99 | +  })
 | 
	
		
			
			|  | 100 | +  .fetch('GET', 'http://www.example.com/file/example.zip', {
 | 
	
		
			
			|  | 101 | +    some headers ..
 | 
	
		
			
			|  | 102 | +  })
 | 
	
		
			
			|  | 103 | +  .then((res) => {
 | 
	
		
			
			|  | 104 | +    // the temp file path with file extension `png`
 | 
	
		
			
			|  | 105 | +    console.log('The file saved to ', res.path())
 | 
	
		
			
			|  | 106 | +    // Beware that when using a file path as Image source on Android,
 | 
	
		
			
			|  | 107 | +    // you must prepend "file://"" before the file path
 | 
	
		
			
			|  | 108 | +    imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' : '' + res.path() }}/>
 | 
	
		
			
			|  | 109 | +  })
 | 
	
		
			
			|  | 110 | +```
 | 
	
		
			
			|  | 111 | +
 | 
	
		
			
			|  | 112 | +What's more, if you prefer a specific path, rather a random generated path, you can use `path` option. We've added a [getSystemDirs](#user-content-getsysdirs) API in v0.5.0 that lists several common used directories.
 | 
	
		
			
			|  | 113 | +
 | 
	
		
			
			|  | 114 | +```js
 | 
	
		
			
			|  | 115 | +RNFetchBlob.getSystemDirs().then((dirs) => {
 | 
	
		
			
			|  | 116 | +  RNFetchBlob
 | 
	
		
			
			|  | 117 | +    .config({
 | 
	
		
			
			|  | 118 | +      path : dirs.DocumentDir + 'path-to-file.anything'
 | 
	
		
			
			|  | 119 | +    })
 | 
	
		
			
			|  | 120 | +    .fetch('GET', 'http://www.example.com/file/example.zip', {
 | 
	
		
			
			|  | 121 | +      some headers ..
 | 
	
		
			
			|  | 122 | +    })
 | 
	
		
			
			|  | 123 | +    .then((res) => {
 | 
	
		
			
			|  | 124 | +      // the path should be dirs.DocumentDir + 'path-to-file.anything'
 | 
	
		
			
			|  | 125 | +      console.log('The file saved to ', res.path())
 | 
	
		
			
			|  | 126 | +    })
 | 
	
		
			
			|  | 127 | +})
 | 
	
		
			
			|  | 128 | +```
 | 
	
		
			
			|  | 129 | +
 | 
	
		
			
			| 66 | 130 |  ####  Upload example : Dropbox [files-upload](https://www.dropbox.com/developers/documentation/http/documentation#files-upload) API
 | 
	
		
			
			| 67 | 131 |  
 | 
	
		
			
			| 68 | 132 |  `react-native-fetch-blob` will convert the base64 string in `body` to binary format using native API, this process will be  done in a new thread, so it's async.
 | 
	
	
		
			
			|  | @@ -87,6 +151,29 @@ RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
 | 
	
		
			
			| 87 | 151 |    })
 | 
	
		
			
			| 88 | 152 |  ```
 | 
	
		
			
			| 89 | 153 |  
 | 
	
		
			
			|  | 154 | +#### Upload a file from storage
 | 
	
		
			
			|  | 155 | +
 | 
	
		
			
			|  | 156 | +If you're going to use a `file` in file system as request body, just push the path with prefix `RNFetchBlob-file://`.
 | 
	
		
			
			|  | 157 | +
 | 
	
		
			
			|  | 158 | +```js
 | 
	
		
			
			|  | 159 | +RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
 | 
	
		
			
			|  | 160 | +    Authorization : "Bearer access-token...",
 | 
	
		
			
			|  | 161 | +    'Dropbox-API-Arg': JSON.stringify({
 | 
	
		
			
			|  | 162 | +      path : '/img-from-react-native.png',
 | 
	
		
			
			|  | 163 | +      mode : 'add',
 | 
	
		
			
			|  | 164 | +      autorename : true,
 | 
	
		
			
			|  | 165 | +      mute : false
 | 
	
		
			
			|  | 166 | +    }),
 | 
	
		
			
			|  | 167 | +    'Content-Type' : 'application/octet-stream',
 | 
	
		
			
			|  | 168 | +  }, 'RNFetchBlob-file://' + PATH_TO_THE_FILE)
 | 
	
		
			
			|  | 169 | +  .then((res) => {
 | 
	
		
			
			|  | 170 | +    console.log(res.text())
 | 
	
		
			
			|  | 171 | +  })
 | 
	
		
			
			|  | 172 | +  .catch((err) => {
 | 
	
		
			
			|  | 173 | +    // error handling ..
 | 
	
		
			
			|  | 174 | +  })
 | 
	
		
			
			|  | 175 | +```
 | 
	
		
			
			|  | 176 | +
 | 
	
		
			
			| 90 | 177 |  #### Multipart/form-data example : Post form data with file and data
 | 
	
		
			
			| 91 | 178 |  
 | 
	
		
			
			| 92 | 179 |  In `version >= 0.3.0` you can also post files with form data,  just put an array in `body`, with object elements with property `name`, `data`, and `filename`(optional).
 | 
	
	
		
			
			|  | @@ -115,6 +202,30 @@ Elements have property `filename` will be transformed into binary format, otherw
 | 
	
		
			
			| 115 | 202 |    })
 | 
	
		
			
			| 116 | 203 |  ```
 | 
	
		
			
			| 117 | 204 |  
 | 
	
		
			
			|  | 205 | +What if some fields contains a file in file storage ? Just like [upload a file from storage](#user-content-upload-a-file-from-storage) example, change the `data` to path of the file with a prefix `RNFetchBlob-file://`
 | 
	
		
			
			|  | 206 | +
 | 
	
		
			
			|  | 207 | +```js
 | 
	
		
			
			|  | 208 | +
 | 
	
		
			
			|  | 209 | +  RNFetchBlob.fetch('POST', 'http://www.example.com/upload-form', {
 | 
	
		
			
			|  | 210 | +    Authorization : "Bearer access-token",
 | 
	
		
			
			|  | 211 | +    otherHeader : "foo",
 | 
	
		
			
			|  | 212 | +    'Content-Type' : 'multipart/form-data',
 | 
	
		
			
			|  | 213 | +  }, [
 | 
	
		
			
			|  | 214 | +    // append field data from file path
 | 
	
		
			
			|  | 215 | +    { name : 'avatar', filename : 'avatar.png', data: 'RNFetchBlob-file://' + PATH_TO_THE_FILE},
 | 
	
		
			
			|  | 216 | +    // elements without property `filename` will be sent as plain text
 | 
	
		
			
			|  | 217 | +    { name : 'name', data : 'user'},
 | 
	
		
			
			|  | 218 | +    { name : 'info', data : JSON.stringify({
 | 
	
		
			
			|  | 219 | +      mail : 'example@example.com',
 | 
	
		
			
			|  | 220 | +      tel : '12345678'
 | 
	
		
			
			|  | 221 | +    })},
 | 
	
		
			
			|  | 222 | +  ]).then((resp) => {
 | 
	
		
			
			|  | 223 | +    // ...
 | 
	
		
			
			|  | 224 | +  }).catch((err) => {
 | 
	
		
			
			|  | 225 | +    // ...
 | 
	
		
			
			|  | 226 | +  })
 | 
	
		
			
			|  | 227 | +```
 | 
	
		
			
			|  | 228 | +
 | 
	
		
			
			| 118 | 229 |  #### Upload/Download progress
 | 
	
		
			
			| 119 | 230 |  
 | 
	
		
			
			| 120 | 231 |  In `version >= 0.4.2` it is possible to know the upload/download progress.
 | 
	
	
		
			
			|  | @@ -184,10 +295,11 @@ When `fetch` success, it resolve a `FetchBlobResponse` object as first argument.
 | 
	
		
			
			| 184 | 295 |  
 | 
	
		
			
			| 185 | 296 |  | Version | |
 | 
	
		
			
			| 186 | 297 |  |---|---|
 | 
	
		
			
			| 187 |  | -| 0.3 | Upload/Download octet-stream and form-data |
 | 
	
		
			
			| 188 |  | -| 0.4 | Add base-64 encode/decode library and API |
 | 
	
		
			
			|  | 298 | +| ~0.3.0 | Upload/Download octet-stream and form-data |
 | 
	
		
			
			|  | 299 | +| 0.4.0 | Add base-64 encode/decode library and API |
 | 
	
		
			
			| 189 | 300 |  | 0.4.1 | Fixe upload form-data missing file extension problem on Android |
 | 
	
		
			
			| 190 | 301 |  | 0.4.2 | Supports upload/download progress |
 | 
	
		
			
			|  | 302 | +| 0.5.0 | Upload/download with direct access to file storage, and also supports read file with file stream |
 | 
	
		
			
			| 191 | 303 |  
 | 
	
		
			
			| 192 | 304 |  ### Upcoming Features
 | 
	
		
			
			| 193 | 305 |  
 | 
	
	
		
			
			|  | @@ -199,5 +311,5 @@ We are now working on v0.5.0, there will be some new features.
 | 
	
		
			
			| 199 | 311 |  
 | 
	
		
			
			| 200 | 312 |  ### Development
 | 
	
		
			
			| 201 | 313 |  
 | 
	
		
			
			| 202 |  | -If you're insterested in hacking this module, check our [development guide](https://github.com/wkh237/react-native-fetch-blob/wiki/Development-Guide), there might be something helpful. 
 | 
	
		
			
			|  | 314 | +If you're insterested in hacking this module, check our [development guide](https://github.com/wkh237/react-native-fetch-blob/wiki/Development-Guide), there might be something helpful.
 | 
	
		
			
			| 203 | 315 |  Please feel free to make a PR or file an issue.
 |