react-native-blob-util 0.13.18 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +542 -401
  2. package/android/build.gradle +1 -0
  3. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +89 -25
  4. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +14 -15
  5. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +10 -6
  6. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +115 -289
  7. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java +10 -0
  8. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +314 -0
  9. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilPackage.java +6 -2
  10. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +46 -22
  11. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilStream.java +287 -0
  12. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilUtils.java +57 -2
  13. package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +9 -0
  14. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -0
  15. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -0
  16. package/class/ReactNativeBlobUtilBlobResponse.js +1 -1
  17. package/fs.js +44 -4
  18. package/index.d.ts +121 -1
  19. package/index.js +2 -0
  20. package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +6 -4
  21. package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +6 -0
  22. package/ios/ReactNativeBlobUtilConst.h +1 -0
  23. package/ios/ReactNativeBlobUtilConst.m +1 -0
  24. package/ios/ReactNativeBlobUtilFS.h +3 -1
  25. package/ios/ReactNativeBlobUtilFS.m +33 -0
  26. package/ios/ReactNativeBlobUtilFileTransformer.h +24 -0
  27. package/ios/ReactNativeBlobUtilFileTransformer.m +21 -0
  28. package/ios/ReactNativeBlobUtilReqBuilder.m +2 -2
  29. package/ios/ReactNativeBlobUtilRequest.m +30 -1
  30. package/mediacollection.js +38 -0
  31. package/package.json +1 -1
  32. package/polyfill/Fetch.js +4 -2
  33. package/scripts/prelink.js +1 -1
  34. package/types.js +4 -0
package/README.md CHANGED
@@ -1,16 +1,22 @@
1
1
  # react-native-blob-util
2
- [![release](https://img.shields.io/github/release/RonRadtke/react-native-blob-util.svg?style=flat-square)](https://github.com/RonRadtke/react-native-blob-util/releases) [![npm](https://img.shields.io/npm/v/react-native-blob-util.svg?style=flat-square)](https://www.npmjs.com/package/react-native-blob-util) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg?style=flat-square) [![](https://img.shields.io/badge/Wiki-Public-brightgreen.svg?style=flat-square)](https://github.com/joltup/react-native-blob-util/wiki) [![npm](https://img.shields.io/npm/l/react-native-blob-util.svg?maxAge=2592000&style=flat-square)]()
2
+
3
+ [![release](https://img.shields.io/github/release/RonRadtke/react-native-blob-util.svg?style=flat-square)](https://github.com/RonRadtke/react-native-blob-util/releases) [![npm](https://img.shields.io/npm/v/react-native-blob-util.svg?style=flat-square)](https://www.npmjs.com/package/react-native-blob-util) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg?style=flat-square) [![](https://img.shields.io/badge/Wiki-Public-brightgreen.svg?style=flat-square)](https://github.com/RonRadtke/react-native-blob-util/wiki) [![npm](https://img.shields.io/npm/l/react-native-blob-util.svg?maxAge=2592000&style=flat-square)]()
3
4
 
4
5
  A project committed to making file access and data transfer easier and more efficient for React Native developers.
6
+
5
7
  # I forked this project to continue working on it.
6
- This project is a fork of https://www.npmjs.com/package/rn-fetch-blob which on the other hand is a fork of https://github.com/wkh237/react-native-fetch-blob.
7
- Both the original repository and its first fork are not maintained anymore.
8
+
9
+ This project is a fork of https://www.npmjs.com/package/rn-fetch-blob which on the other hand is a fork of https://github.com/wkh237/react-native-fetch-blob. Both the original repository and its first fork are not maintained anymore.
8
10
 
9
11
  The project will be continued in this repository. React-Native-Blob-Util is fully compatible with RN-Fetch-Blob and React-Native-Fetch-Blob. If you want to support the project feel free to contact me or create a pull request with your feature.
12
+
10
13
  # Version Compatibility Warning
14
+
11
15
  react-native-blob-util version 0.10.16 and up is only compatible with react native 0.60 and up.
12
16
 
13
17
  ## Features
18
+
19
+ - Access and write data to Android MedaiaStore (e.g. Downloads folder on devices > Android 9)
14
20
  - Transfer data directly from/to storage without BASE64 bridging
15
21
  - File API supports regular files, Asset files, and CameraRoll files
16
22
  - Native-to-native file manipulation API, reduce JS bridging performance loss
@@ -19,35 +25,33 @@ react-native-blob-util version 0.10.16 and up is only compatible with react nati
19
25
  - JSON stream supported base on [Oboe.js](https://github.com/jimhigson/oboe.js/) @jimhigson
20
26
 
21
27
  ## Android 10 & 11
22
- Android 10 introduced scoped storage for apps. Apps no longer can create own directories directly on the external storage or access files outside of the apps own directories.
23
- This currently limits the library to create files in its own directory. This directory is not accessible by other apps.
24
- If you want to open the files with another app (e.g. images) you can save it to the downloadDir and then open the file with actionViewIntent.
25
-
26
- This is leading to the problem that all files are deleted when the app is being removed.
27
- The best and recommanded option to address this issue is, moving the files to a media collection (e.g. galery or downloads). The possibility to do this will be implemented in a future release.
28
28
 
29
+ Android 10 introduced scoped storage for apps. Apps no longer can create own directories directly on the external storage or access files outside the apps own directories. With version 0.14.0 support for the media storage is implemented. For more information please see the chapter about the mediastore API.
30
+ [test](###android-media-storage)
29
31
  For more information see: https://developer.android.com/training/data-storage
30
- ## TOC (visit [Wiki](https://github.com/joltup/react-native-blob-util/wiki) to get the complete documentation)
32
+
33
+ ## TOC (visit [Wiki](https://github.com/RonRadtke/react-native-blob-util/wiki) to get the complete documentation)
34
+
31
35
  * [About](#user-content-about)
32
36
  * [Installation](#user-content-installation)
33
37
  * [HTTP Data Transfer](#user-content-http-data-transfer)
34
- * [Regular Request](#user-content-regular-request)
35
- * [Download file](#download-example-fetch-files-that-need-authorization-token)
36
- * [Upload file](#user-content-upload-example--dropbox-files-upload-api)
37
- * [Multipart/form upload](#user-content-multipartform-data-example--post-form-data-with-file-and-data)
38
- * [Upload/Download progress](#user-content-uploaddownload-progress)
39
- * [Cancel HTTP request](#user-content-cancel-request)
40
- * [Android Media Scanner, and Download Manager Support](#user-content-android-media-scanner-and-download-manager-support)
41
- * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
42
- * [Transfer Encoding](#user-content-transfer-encoding)
43
- * [Drop-in Fetch Replacement](#user-content-drop-in-fetch-replacement)
38
+ * [Regular Request](#user-content-regular-request)
39
+ * [Download file](#download-example-fetch-files-that-need-authorization-token)
40
+ * [Upload file](#user-content-upload-example--dropbox-files-upload-api)
41
+ * [Multipart/form upload](#user-content-multipartform-data-example--post-form-data-with-file-and-data)
42
+ * [Upload/Download progress](#user-content-uploaddownload-progress)
43
+ * [Cancel HTTP request](#user-content-cancel-request)
44
+ * [Android Media Scanner, and Download Manager Support](#user-content-android-media-scanner-and-download-manager-support)
45
+ * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
46
+ * [Transfer Encoding](#user-content-transfer-encoding)
47
+ * [Drop-in Fetch Replacement](#user-content-drop-in-fetch-replacement)
44
48
  * [File System](#user-content-file-system)
45
- * [File access](#user-content-file-access)
46
- * [File stream](#user-content-file-stream)
47
- * [Manage cached files](#user-content-cache-file-management)
49
+ * [File access](#user-content-file-access)
50
+ * [File stream](#user-content-file-stream)
51
+ * [Manage cached files](#user-content-cache-file-management)
48
52
  * [Web API Polyfills](#user-content-web-api-polyfills)
49
53
  * [Performance Tips](#user-content-performance-tips)
50
- * [API References](https://github.com/joltup/react-native-blob-util/wiki/Fetch-API)
54
+ * [API References](https://github.com/RonRadtke/react-native-blob-util/wiki/Fetch-API)
51
55
  * [Caveats](#user-content-caveats)
52
56
  * [Development](#user-content-development)
53
57
 
@@ -59,7 +63,6 @@ It is committed to making file access and transfer easier and more efficient for
59
63
 
60
64
  In `0.8.0` we introduced experimental Web API polyfills that make it possible to use browser-based libraries in React Native, such as, [FireBase JS SDK](https://github.com/joltup/rn-firebase-storage-upload-sample)
61
65
 
62
-
63
66
  ## Installation
64
67
 
65
68
  Install package from npm
@@ -81,15 +84,17 @@ After `0.10.3` you can install this package directly from Github
81
84
  # replace <branch_name> with any one of the branches
82
85
  npm install --save github:RonRadtke/react-native-blob-util#<branch_name>
83
86
  ```
87
+
84
88
  **Okhttp**
85
89
 
86
- For using the library okhttp3 is required. It's in general included in react-native.
87
- The library uses the okhttp version shipped with react-native or used by your app.
88
- For very old devices android devices okhttp 3.12 can be used.
90
+ For using the library okhttp3 is required. It's in general included in react-native. The library uses the okhttp version shipped with react-native or used by your app. For very old devices android devices okhttp 3.12 can be used.
89
91
 
90
92
  **Manually Link Native Modules**
91
93
 
92
- If automatically linking doesn't work for you, see instructions on [manually linking](https://github.com/joltup/react-native-blob-util/wiki/Manually-Link-Package#index).
94
+ If you're using RN 0.60 or higher, manuall linking should not be required anymore.
95
+
96
+
97
+ If automatically linking doesn't work for you, see instructions on [manually linking](https://github.com/RonRadtke/react-native-blob-util/wiki/Manually-Link-Package#index).
93
98
 
94
99
  **Automatically Link Native Modules**
95
100
 
@@ -117,7 +122,7 @@ pre 0.29 projects
117
122
  RNFB_ANDROID_PERMISSIONS=true rnpm link
118
123
  ```
119
124
 
120
- The link script might not take effect if you have non-default project structure, please visit [the wiki](https://github.com/joltup/react-native-blob-util/wiki/Manually-Link-Package) to link the package manually.
125
+ The link script might not take effect if you have non-default project structure, please visit [the wiki](https://github.com/RonRadtke/react-native-blob-util/wiki/Manually-Link-Package) to link the package manually.
121
126
 
122
127
  **Grant Permission to External storage for Android 5.0 or lower**
123
128
 
@@ -174,7 +179,7 @@ import ReactNativeBlobUtil from 'react-native-blob-util'
174
179
 
175
180
  ES5
176
181
 
177
- If you're using ES5 require statement to load the module, please add `default`. See [here](https://github.com/joltup/react-native-blob-util/wiki/Trouble-Shooting#ReactNativeBlobUtilfetch-is-not-a-function) for more detail.
182
+ If you're using ES5 require statement to load the module, please add `default`. See [here](https://github.com/RonRadtke/react-native-blob-util/wiki/Trouble-Shooting#ReactNativeBlobUtilfetch-is-not-a-function) for more detail.
178
183
 
179
184
  ```
180
185
  var ReactNativeBlobUtil = require('react-native-blob-util').default
@@ -182,7 +187,6 @@ var ReactNativeBlobUtil = require('react-native-blob-util').default
182
187
 
183
188
  ## HTTP Data Transfer
184
189
 
185
-
186
190
  ### Regular Request
187
191
 
188
192
  After `0.8.0` react-native-blob-util automatically decides how to send the body by checking its type and `Content-Type` in the header. The rule is described in the following diagram
@@ -193,8 +197,8 @@ To sum up:
193
197
 
194
198
  - To send a form data, the `Content-Type` header does not matter. When the body is an `Array` we will set proper content type for you.
195
199
  - To send binary data, you have two choices, use BASE64 encoded string or path points to a file contains the body.
196
- - If the `Content-Type` containing substring`;BASE64` or `application/octet` the given body will be considered as a BASE64 encoded data which will be decoded to binary data as the request body.
197
- - Otherwise, if a string starts with `ReactNativeBlobUtil-file://` (which can simply be done by `ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE)`), it will try to find the data from the URI string after `ReactNativeBlobUtil-file://` and use it as the request body.
200
+ - If the `Content-Type` containing substring`;BASE64` or `application/octet` the given body will be considered as a BASE64 encoded data which will be decoded to binary data as the request body.
201
+ - Otherwise, if a string starts with `ReactNativeBlobUtil-file://` (which can simply be done by `ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE)`), it will try to find the data from the URI string after `ReactNativeBlobUtil-file://` and use it as the request body.
198
202
  - To send the body as-is, simply use a `Content-Type` header not containing `;BASE64` or `application/octet`.
199
203
 
200
204
  > It is Worth to mentioning that the HTTP request uses cache by default, if you're going to disable it simply add a Cache-Control header `'Cache-Control' : 'no-store'`
@@ -209,26 +213,27 @@ Most simple way is download to memory and stored as BASE64 encoded string, this
209
213
 
210
214
  // send http request in a new thread (using native code)
211
215
  ReactNativeBlobUtil.fetch('GET', 'http://www.example.com/images/img1.png', {
212
- Authorization : 'Bearer access-token...',
216
+ Authorization: 'Bearer access-token...',
213
217
  // more headers ..
214
- })
215
- .then((res) => {
216
- let status = res.info().status;
217
-
218
- if(status == 200) {
219
- // the conversion is done in native code
220
- let base64Str = res.base64()
221
- // the following conversions are done in js, it's SYNC
222
- let text = res.text()
223
- let json = res.json()
224
- } else {
225
- // handle other status codes
226
- }
227
- })
228
- // Something went wrong:
229
- .catch((errorMessage, statusCode) => {
230
- // error handling
231
- })
218
+ })
219
+ .then((res) => {
220
+ let status = res.info().status;
221
+
222
+ if (status == 200) {
223
+ // the conversion is done in native code
224
+ let base64Str = res.base64()
225
+ // the following conversions are done in js, it's SYNC
226
+ let text = res.text()
227
+ let json = res.json()
228
+ }
229
+ else {
230
+ // handle other status codes
231
+ }
232
+ })
233
+ // Something went wrong:
234
+ .catch((errorMessage, statusCode) => {
235
+ // error handling
236
+ })
232
237
  ```
233
238
 
234
239
  ### Download to storage directly
@@ -239,18 +244,18 @@ If the response data is large, that would be a bad idea to convert it into BASE6
239
244
 
240
245
  ```js
241
246
  ReactNativeBlobUtil
242
- .config({
243
- // add this option that makes response data to be stored as a file,
244
- // this is much more performant.
245
- fileCache : true,
246
- })
247
- .fetch('GET', 'http://www.example.com/file/example.zip', {
248
- //some headers ..
249
- })
250
- .then((res) => {
251
- // the temp file path
252
- console.log('The file saved to ', res.path())
253
- })
247
+ .config({
248
+ // add this option that makes response data to be stored as a file,
249
+ // this is much more performant.
250
+ fileCache: true,
251
+ })
252
+ .fetch('GET', 'http://www.example.com/file/example.zip', {
253
+ //some headers ..
254
+ })
255
+ .then((res) => {
256
+ // the temp file path
257
+ console.log('The file saved to ', res.path())
258
+ })
254
259
  ```
255
260
 
256
261
  **Set Temp File Extension**
@@ -259,70 +264,90 @@ Sometimes you might need a file extension for some reason. For example, when usi
259
264
 
260
265
  ```js
261
266
  ReactNativeBlobUtil
262
- .config({
263
- fileCache : true,
264
- // by adding this option, the temp files will have a file extension
265
- appendExt : 'png'
266
- })
267
- .fetch('GET', 'http://www.example.com/file/example.zip', {
268
- //some headers ..
269
- })
270
- .then((res) => {
271
- // the temp file path with file extension `png`
272
- console.log('The file saved to ', res.path())
273
- // Beware that when using a file path as Image source on Android,
274
- // you must prepend "file://"" before the file path
275
- imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>
276
- })
267
+ .config({
268
+ fileCache: true,
269
+ // by adding this option, the temp files will have a file extension
270
+ appendExt: 'png'
271
+ })
272
+ .fetch('GET', 'http://www.example.com/file/example.zip', {
273
+ //some headers ..
274
+ })
275
+ .then((res) => {
276
+ // the temp file path with file extension `png`
277
+ console.log('The file saved to ', res.path())
278
+ // Beware that when using a file path as Image source on Android,
279
+ // you must prepend "file://"" before the file path
280
+ imageView = <Image source={{uri: Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path()}}/>
281
+ })
277
282
  ```
278
283
 
279
284
  **Use Specific File Path**
280
285
 
281
- If you prefer a particular file path rather than randomly generated one, you can use `path` option. We've added [several constants](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#dirs) in v0.5.0 which represents commonly used directories.
286
+ If you prefer a particular file path rather than randomly generated one, you can use `path` option. We've added [several constants](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#dirs) in v0.5.0 which represents commonly used directories.
282
287
 
283
288
  ```js
284
289
  let dirs = ReactNativeBlobUtil.fs.dirs
285
290
  ReactNativeBlobUtil
286
- .config({
287
- // response data will be saved to this path if it has access right.
288
- path : dirs.DocumentDir + '/path-to-file.anything'
289
- })
290
- .fetch('GET', 'http://www.example.com/file/example.zip', {
291
- //some headers ..
292
- })
293
- .then((res) => {
294
- // the path should be dirs.DocumentDir + 'path-to-file.anything'
295
- console.log('The file saved to ', res.path())
296
- })
291
+ .config({
292
+ // response data will be saved to this path if it has access right.
293
+ path: dirs.DocumentDir + '/path-to-file.anything'
294
+ })
295
+ .fetch('GET', 'http://www.example.com/file/example.zip', {
296
+ //some headers ..
297
+ })
298
+ .then((res) => {
299
+ // the path should be dirs.DocumentDir + 'path-to-file.anything'
300
+ console.log('The file saved to ', res.path())
301
+ })
297
302
  ```
298
303
 
299
304
  **These files won't be removed automatically, please refer to [Cache File Management](#user-content-cache-file-management)**
300
305
 
301
- #### Upload example : Dropbox [files-upload](https://www.dropbox.com/developers/documentation/http/documentation#files-upload) API
306
+ **Use File Transformer**
307
+
308
+ If you need to perform any processing on the bytes prior to it being written into storage (e.g. if you want it to be encrypted) then you can use `transform` option. NOTE: you will need to set a transformer on the libray (see [Setting a File Transformer](#Setting-A-File-Transformer))
309
+
310
+ ```js
311
+ ReactNativeBlobUtil
312
+ .config({
313
+ // response data will be saved to this path if it has access right.
314
+ path: dirs.DocumentDir + '/path-to-file.anything',
315
+ transform: true
316
+ })
317
+ .fetch('GET', 'http://www.example.com/file/example.zip', {
318
+ //some headers ..
319
+ })
320
+ .then((res) => {
321
+ // the path should be dirs.DocumentDir + 'path-to-file.anything'
322
+ console.log('The file saved to ', res.path())
323
+ })
324
+ ```
325
+
326
+ #### Upload example : Dropbox [files-upload](https://www.dropbox.com/developers/documentation/http/documentation#files-upload) API
302
327
 
303
328
  `react-native-blob-util` will convert the base64 string in `body` to binary format using native API, this process is done in a separated thread so that it won't block your GUI.
304
329
 
305
330
  ```js
306
331
 
307
332
  ReactNativeBlobUtil.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
308
- Authorization : "Bearer access-token...",
333
+ Authorization: "Bearer access-token...",
309
334
  'Dropbox-API-Arg': JSON.stringify({
310
- path : '/img-from-react-native.png',
311
- mode : 'add',
312
- autorename : true,
313
- mute : false
335
+ path: '/img-from-react-native.png',
336
+ mode: 'add',
337
+ autorename: true,
338
+ mute: false
314
339
  }),
315
- 'Content-Type' : 'application/octet-stream',
340
+ 'Content-Type': 'application/octet-stream',
316
341
  // here's the body you're going to send, should be a BASE64 encoded string
317
342
  // (you can use "base64"(refer to the library 'mathiasbynens/base64') APIs to make one).
318
343
  // The data will be converted to "byte array"(say, blob) before request sent.
319
- }, base64ImageString)
320
- .then((res) => {
321
- console.log(res.text())
322
- })
323
- .catch((err) => {
324
- // error handling ..
325
- })
344
+ }, base64ImageString)
345
+ .then((res) => {
346
+ console.log(res.text())
347
+ })
348
+ .catch((err) => {
349
+ // error handling ..
350
+ })
326
351
  ```
327
352
 
328
353
  ### Upload a file from storage
@@ -332,23 +357,23 @@ If you're going to use a `file` as request body, just wrap the path with `wrap`
332
357
  ```js
333
358
  ReactNativeBlobUtil.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
334
359
  // dropbox upload headers
335
- Authorization : "Bearer access-token...",
360
+ Authorization: "Bearer access-token...",
336
361
  'Dropbox-API-Arg': JSON.stringify({
337
- path : '/img-from-react-native.png',
338
- mode : 'add',
339
- autorename : true,
340
- mute : false
362
+ path: '/img-from-react-native.png',
363
+ mode: 'add',
364
+ autorename: true,
365
+ mute: false
341
366
  }),
342
- 'Content-Type' : 'application/octet-stream',
367
+ 'Content-Type': 'application/octet-stream',
343
368
  // Change BASE64 encoded data to a file path with prefix `ReactNativeBlobUtil-file://`.
344
369
  // Or simply wrap the file path with ReactNativeBlobUtil.wrap().
345
- }, ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE))
346
- .then((res) => {
347
- console.log(res.text())
348
- })
349
- .catch((err) => {
350
- // error handling ..
351
- })
370
+ }, ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE))
371
+ .then((res) => {
372
+ console.log(res.text())
373
+ })
374
+ .catch((err) => {
375
+ // error handling ..
376
+ })
352
377
  ```
353
378
 
354
379
  ### Multipart/form-data example: Post form data with file and data
@@ -359,67 +384,71 @@ Elements have property `filename` will be transformed into binary format, otherw
359
384
 
360
385
  ```js
361
386
 
362
- ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
363
- Authorization : "Bearer access-token",
364
- otherHeader : "foo",
365
- 'Content-Type' : 'multipart/form-data',
366
- }, [
387
+ ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
388
+ Authorization: "Bearer access-token",
389
+ otherHeader: "foo",
390
+ 'Content-Type': 'multipart/form-data',
391
+ }, [
367
392
  // element with property `filename` will be transformed into `file` in form data
368
- { name : 'avatar', filename : 'avatar.png', data: binaryDataInBase64},
393
+ {name: 'avatar', filename: 'avatar.png', data: binaryDataInBase64},
369
394
  // custom content type
370
- { name : 'avatar-png', filename : 'avatar-png.png', type:'image/png', data: binaryDataInBase64},
395
+ {name: 'avatar-png', filename: 'avatar-png.png', type: 'image/png', data: binaryDataInBase64},
371
396
  // part file from storage
372
- { name : 'avatar-foo', filename : 'avatar-foo.png', type:'image/foo', data: ReactNativeBlobUtil.wrap(path_to_a_file)},
397
+ {name: 'avatar-foo', filename: 'avatar-foo.png', type: 'image/foo', data: ReactNativeBlobUtil.wrap(path_to_a_file)},
373
398
  // elements without property `filename` will be sent as plain text
374
- { name : 'name', data : 'user'},
375
- { name : 'info', data : JSON.stringify({
376
- mail : 'example@example.com',
377
- tel : '12345678'
378
- })},
379
- ]).then((resp) => {
399
+ {name: 'name', data: 'user'},
400
+ {
401
+ name: 'info', data: JSON.stringify({
402
+ mail: 'example@example.com',
403
+ tel: '12345678'
404
+ })
405
+ },
406
+ ]).then((resp) => {
380
407
  // ...
381
- }).catch((err) => {
408
+ }).catch((err) => {
382
409
  // ...
383
- })
410
+ })
384
411
  ```
385
412
 
386
413
  What if you want to append a file to form data? Just like [upload a file from storage](#user-content-upload-a-file-from-storage) example, wrap `data` by `wrap` API (this feature is only available for `version >= v0.5.0`). On version >= `0.6.2`, it is possible to set custom MIME type when appending a file to form data. But keep in mind when the file is large it's likely to crash your app. Please consider use other strategy (see [#94](https://github.com/joltup/react-native-blob-util/issues/94)).
387
414
 
388
415
  ```js
389
416
 
390
- ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
391
- Authorization : "Bearer access-token",
392
- otherHeader : "foo",
417
+ ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
418
+ Authorization: "Bearer access-token",
419
+ otherHeader: "foo",
393
420
  // this is required, otherwise it won't be process as a multipart/form-data request
394
- 'Content-Type' : 'multipart/form-data',
395
- }, [
421
+ 'Content-Type': 'multipart/form-data',
422
+ }, [
396
423
  // append field data from file path
397
424
  {
398
- name : 'avatar',
399
- filename : 'avatar.png',
400
- // Change BASE64 encoded data to a file path with prefix `ReactNativeBlobUtil-file://`.
401
- // Or simply wrap the file path with ReactNativeBlobUtil.wrap().
402
- data: ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE)
425
+ name: 'avatar',
426
+ filename: 'avatar.png',
427
+ // Change BASE64 encoded data to a file path with prefix `ReactNativeBlobUtil-file://`.
428
+ // Or simply wrap the file path with ReactNativeBlobUtil.wrap().
429
+ data: ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE)
403
430
  },
404
431
  {
405
- name : 'ringtone',
406
- filename : 'ring.mp3',
407
- // use custom MIME type
408
- type : 'application/mp3',
409
- // upload a file from asset is also possible in version >= 0.6.2
410
- data : ReactNativeBlobUtil.wrap(ReactNativeBlobUtil.fs.asset('default-ringtone.mp3'))
411
- }
432
+ name: 'ringtone',
433
+ filename: 'ring.mp3',
434
+ // use custom MIME type
435
+ type: 'application/mp3',
436
+ // upload a file from asset is also possible in version >= 0.6.2
437
+ data: ReactNativeBlobUtil.wrap(ReactNativeBlobUtil.fs.asset('default-ringtone.mp3'))
438
+ },
412
439
  // elements without property `filename` will be sent as plain text
413
- { name : 'name', data : 'user'},
414
- { name : 'info', data : JSON.stringify({
415
- mail : 'example@example.com',
416
- tel : '12345678'
417
- })},
418
- ]).then((resp) => {
440
+ {name: 'name', data: 'user'},
441
+ {
442
+ name: 'info', data: JSON.stringify({
443
+ mail: 'example@example.com',
444
+ tel: '12345678'
445
+ })
446
+ },
447
+ ]).then((resp) => {
419
448
  // ...
420
- }).catch((err) => {
449
+ }).catch((err) => {
421
450
  // ...
422
- })
451
+ })
423
452
  ```
424
453
 
425
454
  ### Upload/Download progress
@@ -428,47 +457,46 @@ In `version >= 0.4.2` it is possible to know the upload/download progress. After
428
457
 
429
458
  ```js
430
459
  ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload', {
431
- //... some headers,
432
- 'Content-Type' : 'octet-stream'
433
- }, base64DataString)
434
- // listen to upload progress event
435
- .uploadProgress((written, total) => {
436
- console.log('uploaded', written / total)
437
- })
438
- // listen to download progress event
439
- .progress((received, total) => {
440
- console.log('progress', received / total)
441
- })
442
- .then((resp) => {
443
- // ...
444
- })
445
- .catch((err) => {
446
- // ...
447
- })
460
+ //... some headers,
461
+ 'Content-Type': 'octet-stream'
462
+ }, base64DataString)
463
+ // listen to upload progress event
464
+ .uploadProgress((written, total) => {
465
+ console.log('uploaded', written / total)
466
+ })
467
+ // listen to download progress event
468
+ .progress((received, total) => {
469
+ console.log('progress', received / total)
470
+ })
471
+ .then((resp) => {
472
+ // ...
473
+ })
474
+ .catch((err) => {
475
+ // ...
476
+ })
448
477
  ```
449
478
 
450
- In `0.9.6`, you can specify an object as the first argument which contains `count` and `interval`, to the frequency of progress event (this will be done in the native context a reduce RCT bridge overhead). Notice that `count` argument will not work if the server does not provide response content length.
451
-
479
+ In `0.9.6`, you can specify an object as the first argument which contains `count` and `interval`, to the frequency of progress event (this will be done in the native context a reduce RCT bridge overhead). Notice that `count` argument will not work if the server does not provide response content length.
452
480
 
453
481
  ```js
454
482
  ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload', {
455
- //... some headers,
456
- 'Content-Type' : 'octet-stream'
457
- }, base64DataString)
458
- // listen to upload progress event, emit every 250ms
459
- .uploadProgress({ interval : 250 },(written, total) => {
460
- console.log('uploaded', written / total)
461
- })
462
- // listen to download progress event, every 10%
463
- .progress({ count : 10 }, (received, total) => {
464
- console.log('progress', received / total)
465
- })
466
- .then((resp) => {
467
- // ...
468
- })
469
- .catch((err) => {
470
- // ...
471
- })
483
+ //... some headers,
484
+ 'Content-Type': 'octet-stream'
485
+ }, base64DataString)
486
+ // listen to upload progress event, emit every 250ms
487
+ .uploadProgress({interval: 250}, (written, total) => {
488
+ console.log('uploaded', written / total)
489
+ })
490
+ // listen to download progress event, every 10%
491
+ .progress({count: 10}, (received, total) => {
492
+ console.log('progress', received / total)
493
+ })
494
+ .then((resp) => {
495
+ // ...
496
+ })
497
+ .catch((err) => {
498
+ // ...
499
+ })
472
500
  ```
473
501
 
474
502
  ### Cancel Request
@@ -478,13 +506,15 @@ After `0.7.0` it is possible to cancel an HTTP request. Upon cancellation, it th
478
506
  ```js
479
507
  let task = ReactNativeBlobUtil.fetch('GET', 'http://example.com/file/1')
480
508
 
481
- task.then(() => { ... })
482
- // handle request cancelled rejection
483
- .catch((err) => {
484
- console.log(err)
485
- })
509
+ task.then(() => { ...
510
+ })
511
+ // handle request cancelled rejection
512
+ .catch((err) => {
513
+ console.log(err)
514
+ })
486
515
  // cancel the request, the callback function is optional
487
- task.cancel((err) => { ... })
516
+ task.cancel((err) => { ...
517
+ })
488
518
 
489
519
  ```
490
520
 
@@ -494,11 +524,11 @@ task.cancel((err) => { ... })
494
524
 
495
525
  If you have existing code that uses `whatwg-fetch`(the official **fetch**), it's not necessary to replace them with `ReactNativeBlobUtil.fetch`, you can simply use our **Fetch Replacement**. The difference between Official them is official fetch uses [whatwg-fetch](https://github.com/github/fetch) which wraps XMLHttpRequest polyfill under the hood. It's a great library for web developers, but does not play very well with RN. Our implementation is simply a wrapper of our `fetch` and `fs` APIs, so you can access all the features we provided.
496
526
 
497
- [See document and examples](https://github.com/joltup/react-native-blob-util/wiki/Fetch-API#fetch-replacement)
527
+ [See document and examples](https://github.com/RonRadtke/react-native-blob-util/wiki/Fetch-API#fetch-replacement)
498
528
 
499
529
  ### Android Media Scanner, and Download Manager Support
500
530
 
501
- If you want to make a file in `External Storage` becomes visible in Picture, Downloads, or other built-in apps, you will have to use `Media Scanner` or `Download Manager`.
531
+ If you want to make a file in `External Storage` becomes visible in Picture, Downloads, or other built-in apps, you will have to use `Media Scanner` or `Download Manager` or the `Media Storage`.
502
532
 
503
533
  **Media Scanner**
504
534
 
@@ -507,18 +537,18 @@ Media scanner scans the file and categorizes by given MIME type, if MIME type no
507
537
  ```js
508
538
 
509
539
  ReactNativeBlobUtil
510
- .config({
511
- // DCIMDir is in external storage
512
- path : dirs.DCIMDir + '/music.mp3'
513
- })
514
- .fetch('GET', 'http://example.com/music.mp3')
515
- .then((res) => ReactNativeBlobUtil.fs.scanFile([ { path : res.path(), mime : 'audio/mpeg' } ]))
516
- .then(() => {
517
- // scan file success
518
- })
519
- .catch((err) => {
520
- // scan file error
521
- })
540
+ .config({
541
+ // DCIMDir is in external storage
542
+ path: dirs.DCIMDir + '/music.mp3'
543
+ })
544
+ .fetch('GET', 'http://example.com/music.mp3')
545
+ .then((res) => ReactNativeBlobUtil.fs.scanFile([{path: res.path(), mime: 'audio/mpeg'}]))
546
+ .then(() => {
547
+ // scan file success
548
+ })
549
+ .catch((err) => {
550
+ // scan file error
551
+ })
522
552
  ```
523
553
 
524
554
  **Download Manager**
@@ -533,22 +563,22 @@ When download complete, DownloadManager will generate a file path so that you ca
533
563
 
534
564
  ```js
535
565
  ReactNativeBlobUtil
536
- .config({
537
- addAndroidDownloads : {
538
- useDownloadManager : true, // <-- this is the only thing required
539
- // Optional, override notification setting (default to true)
540
- notification : false,
541
- // Optional, but recommended since android DownloadManager will fail when
542
- // the url does not contains a file extension, by default the mime type will be text/plain
543
- mime : 'text/plain',
544
- description : 'File downloaded by download manager.'
545
- }
546
- })
547
- .fetch('GET', 'http://example.com/file/somefile')
548
- .then((resp) => {
549
- // the path of downloaded file
550
- resp.path()
551
- })
566
+ .config({
567
+ addAndroidDownloads: {
568
+ useDownloadManager: true, // <-- this is the only thing required
569
+ // Optional, override notification setting (default to true)
570
+ notification: false,
571
+ // Optional, but recommended since android DownloadManager will fail when
572
+ // the url does not contains a file extension, by default the mime type will be text/plain
573
+ mime: 'text/plain',
574
+ description: 'File downloaded by download manager.'
575
+ }
576
+ })
577
+ .fetch('GET', 'http://example.com/file/somefile')
578
+ .then((resp) => {
579
+ // the path of downloaded file
580
+ resp.path()
581
+ })
552
582
  ```
553
583
 
554
584
  Your app might not have right to remove/change the file created by Download Manager, therefore you might need to [set custom location to the download task](https://github.com/wkh237/react-native-fetch-blob/issues/236).
@@ -563,22 +593,22 @@ If you need to display a notification upon the file is downloaded to storage (as
563
593
 
564
594
  ```js
565
595
  ReactNativeBlobUtil.config({
566
- fileCache : true,
567
- // android only options, these options be a no-op on IOS
568
- addAndroidDownloads : {
569
- // Show notification when response data transmitted
570
- notification : true,
571
- // Title of download notification
572
- title : 'Great ! Download Success ! :O ',
573
- // File description (not notification description)
574
- description : 'An image file.',
575
- mime : 'image/png',
576
- // Make the file scannable by media scanner
577
- mediaScannable : true,
578
- }
596
+ fileCache: true,
597
+ // android only options, these options be a no-op on IOS
598
+ addAndroidDownloads: {
599
+ // Show notification when response data transmitted
600
+ notification: true,
601
+ // Title of download notification
602
+ title: 'Great ! Download Success ! :O ',
603
+ // File description (not notification description)
604
+ description: 'An image file.',
605
+ mime: 'image/png',
606
+ // Make the file scannable by media scanner
607
+ mediaScannable: true,
608
+ }
579
609
  })
580
- .fetch('GET', 'http://example.com/image1.png')
581
- .then(...)
610
+ .fetch('GET', 'http://example.com/image1.png')
611
+ .then(...)
582
612
  ```
583
613
 
584
614
  **Open Downloaded File with Intent**
@@ -592,19 +622,19 @@ Download and install an APK programmatically
592
622
  const android = ReactNativeBlobUtil.android
593
623
 
594
624
  ReactNativeBlobUtil.config({
595
- addAndroidDownloads : {
596
- useDownloadManager : true,
597
- title : 'awesome.apk',
598
- description : 'An APK that will be installed',
599
- mime : 'application/vnd.android.package-archive',
600
- mediaScannable : true,
601
- notification : true,
625
+ addAndroidDownloads: {
626
+ useDownloadManager: true,
627
+ title: 'awesome.apk',
628
+ description: 'An APK that will be installed',
629
+ mime: 'application/vnd.android.package-archive',
630
+ mediaScannable: true,
631
+ notification: true,
602
632
  }
603
- })
604
- .fetch('GET', `http://www.example.com/awesome.apk`)
605
- .then((res) => {
606
- android.actionViewIntent(res.path(), 'application/vnd.android.package-archive')
607
- })
633
+ })
634
+ .fetch('GET', `http://www.example.com/awesome.apk`)
635
+ .then((res) => {
636
+ android.actionViewIntent(res.path(), 'application/vnd.android.package-archive')
637
+ })
608
638
  ```
609
639
 
610
640
  Or show an image in image viewer
@@ -615,35 +645,106 @@ Or show an image in image viewer
615
645
 
616
646
  ## File System
617
647
 
648
+ ### Android Media Storage
649
+
650
+ Android 10 introduced scoped storage and thus new APIs to store files to Documents, Downloads, Music and other collections. Version 0.14.0 introduced an API to access files in the Media Store but also to create and write to new files in the Media Store. In general you only can access files in the Media Store created by your app, or selected by a picker.
651
+
652
+ #### CopyToMediaStore
653
+
654
+ Copies an existing file from the internal Storage to the Media Store. <br> An exmaple for downloading a file and storing it to the `downloads` collection
655
+
656
+ ```js
657
+ ReactNativeBlobUtil
658
+ .config({
659
+ fileCache: true
660
+ })
661
+ .fetch('GET', 'https://example.de/image.png', {'Accept': 'application/octet-stream'}, JSON.stringify(dat))
662
+ .then(async (res) => {
663
+ let result = await ReactNativeBlobUtil.MediaCollection.copyToMediaStore({
664
+ name: filename, // name of the file
665
+ parentFolder: '', // subdirectory in the Media Store, e.g. HawkIntech/Files to create a folder HawkIntech with a subfolder Files and save the image within this folder
666
+ mimeType: 'image/png' // MIME type of the file
667
+ },
668
+ 'Download', // Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download")
669
+ res.path() // Path to the file being copied in the apps own storage
670
+ );
671
+ });
672
+ ```
673
+
674
+ This example is taking advantage of the fileCache option to directly store the downloaded file and get a path for. <br>
675
+ Currently it's not possible to write data directly from a string recevied by fetch, but only to copy it from a file.
676
+
677
+ #### createMediaFile
678
+
679
+ Creates a new file in the specified collection without writing any data
680
+
681
+ ````js
682
+ let path = await ReactNativeBlobUtil.MediaCollection.createMediafile({
683
+ name: filename, // name of the file
684
+ parentFolder: '', // subdirectory in the Media Store, e.g. HawkIntech/Files to create a folder HawkIntech with a subfolder Files and save the image within this folder
685
+ mimeType: 'image/png' // MIME type of the file
686
+ }, 'Download'// Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download")
687
+ );
688
+ ````
689
+
690
+ #### writeMediaFile
691
+
692
+ Writes data from a file in the apps storage to an existing entry of the Media Store
693
+ ````js
694
+ await ReactNativeBlobUtil.MediaCollection.writeToMediafile('content://....', // content uri of the entry in the media storage
695
+ localpath // path to the file that should be copied
696
+ );
697
+ ````
698
+
699
+ Copies and tranforms data from a file in the apps storage to an existing entry of the Media Store. NOTE: you must set a transformer on the file in order for the transformation to happen (see [Setting a File Transformer](#Setting-A-File-Transformer)).
700
+
701
+ ````js
702
+ await ReactNativeBlobUtil.MediaCollection.writeToMediafileWithTransform('content://....', // content uri of the entry in the media storage
703
+ localpath // path to the file that should be copied
704
+ );
705
+ ````
706
+
707
+ #### copyToInternal
708
+ Copies an entry form the media storage to the apps internal storage.
709
+ ````js
710
+ let destpath = ReactNativeBlobUtil.dirs.CacheDir + '/image.png';
711
+ await ReactNativeBlobUtil.MediaCollection.copyToInternal('content://....', // content uri of the entry in the media storage
712
+ destpath // path to destination the entry should be copied to
713
+ );
714
+ ````
715
+
618
716
  ### File Access
619
717
 
620
718
  File access APIs were made when developing `v0.5.0`, which helping us write tests, and was not planned to be a part of this module. However, we realized that it's hard to find a great solution to manage cached files, everyone who uses this module may need these APIs for their cases.
621
719
 
622
- Before start using file APIs, we recommend read [Differences between File Source](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#differences-between-file-source) first.
720
+ Before start using file APIs, we recommend read [Differences between File Source](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#differences-between-file-source) first.
623
721
 
624
722
  File Access APIs
625
- - [asset (0.6.2)](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#assetfilenamestringstring)
626
- - [dirs](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#dirs)
627
- - [createFile](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#createfilepath-data-encodingpromise)
628
- - [writeFile (0.6.0)](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#writefilepathstring-contentstring--array-encodingstring-appendbooleanpromise)
629
- - [appendFile (0.6.0) ](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#appendfilepathstring-contentstring--arraynumber-encodingstring-promisenumber)
630
- - [readFile (0.6.0)](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#readfilepath-encodingpromise)
631
- - [readStream](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#readstreampath-encoding-buffersize-interval-promisernfbreadstream)
632
- - [hash (0.10.9)](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithm-promise)
633
- - [writeStream](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#writestreampathstring-encodingstringpromise)
634
- - [hash](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithmpromise)
635
- - [unlink](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#unlinkpathstringpromise)
636
- - [mkdir](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#mkdirpathstringpromise)
637
- - [ls](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#lspathstringpromise)
638
- - [mv](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#mvfromstring-tostringpromise)
639
- - [cp](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#cpsrcstring-deststringpromise)
640
- - [exists](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#existspathstringpromise)
641
- - [isDir](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#isdirpathstringpromise)
642
- - [stat](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#statpathstringpromise)
643
- - [lstat](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#lstatpathstringpromise)
644
- - [scanFile (Android only)](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API#scanfilepathstringpromise-androi-only)
645
-
646
- See [File API](https://github.com/joltup/react-native-blob-util/wiki/File-System-Access-API) for more information
723
+
724
+ - [asset (0.6.2)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#assetfilenamestringstring)
725
+ - [dirs](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#dirs)
726
+ - [createFile](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#createfilepath-data-encodingpromise)
727
+ - [writeFile (0.6.0)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#writefilepathstring-contentstring--array-encodingstring-appendbooleanpromise)
728
+ - writeFileWithTransform
729
+ - [appendFile (0.6.0) ](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#appendfilepathstring-contentstring--arraynumber-encodingstring-promisenumber)
730
+ - [readFile (0.6.0)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#readfilepath-encodingpromise)
731
+ - readFileWithTransform
732
+ - [readStream](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#readstreampath-encoding-buffersize-interval-promisernfbreadstream)
733
+ - [hash (0.10.9)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithm-promise)
734
+ - [writeStream](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#writestreampathstring-encodingstringpromise)
735
+ - [hash](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithmpromise)
736
+ - [unlink](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#unlinkpathstringpromise)
737
+ - [mkdir](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#mkdirpathstringpromise)
738
+ - [ls](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#lspathstringpromise)
739
+ - [mv](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#mvfromstring-tostringpromise)
740
+ - [cp](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#cpsrcstring-deststringpromise)
741
+ - [exists](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#existspathstringpromise)
742
+ - [isDir](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#isdirpathstringpromise)
743
+ - [stat](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#statpathstringpromise)
744
+ - [lstat](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#lstatpathstringpromise)
745
+ - [scanFile (Android only)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#scanfilepathstringpromise-androi-only)
746
+
747
+ See [File API](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API) for more information
647
748
 
648
749
  ### File Stream
649
750
 
@@ -656,27 +757,27 @@ When calling `readStream` method, you have to `open` the stream, and start to re
656
757
  ```js
657
758
  let data = ''
658
759
  ReactNativeBlobUtil.fs.readStream(
659
- // file path
660
- PATH_TO_THE_FILE,
661
- // encoding, should be one of `base64`, `utf8`, `ascii`
662
- 'base64',
663
- // (optional) buffer size, default to 4096 (4095 for BASE64 encoded data)
664
- // when reading file in BASE64 encoding, buffer size must be multiples of 3.
665
- 4095)
666
- .then((ifstream) => {
667
- ifstream.open()
668
- ifstream.onData((chunk) => {
669
- // when encoding is `ascii`, chunk will be an array contains numbers
670
- // otherwise it will be a string
671
- data += chunk
672
- })
673
- ifstream.onError((err) => {
674
- console.log('oops', err)
760
+ // file path
761
+ PATH_TO_THE_FILE,
762
+ // encoding, should be one of `base64`, `utf8`, `ascii`
763
+ 'base64',
764
+ // (optional) buffer size, default to 4096 (4095 for BASE64 encoded data)
765
+ // when reading file in BASE64 encoding, buffer size must be multiples of 3.
766
+ 4095)
767
+ .then((ifstream) => {
768
+ ifstream.open()
769
+ ifstream.onData((chunk) => {
770
+ // when encoding is `ascii`, chunk will be an array contains numbers
771
+ // otherwise it will be a string
772
+ data += chunk
773
+ })
774
+ ifstream.onError((err) => {
775
+ console.log('oops', err)
776
+ })
777
+ ifstream.onEnd(() => {
778
+ <Image source={{uri: 'data:image/png,base64' + data}}
675
779
  })
676
- ifstream.onEnd(() => {
677
- <Image source={{ uri : 'data:image/png,base64' + data }}
678
- })
679
- })
780
+ })
680
781
  ```
681
782
 
682
783
  When using `writeStream`, the stream object becomes writable, and you can then perform operations like `write` and `close`.
@@ -685,60 +786,58 @@ Since version 0.10.9 `write()` resolves with the `ReactNativeBlobUtil` instance
685
786
 
686
787
  ```js
687
788
  ReactNativeBlobUtil.fs.writeStream(
688
- PATH_TO_FILE,
689
- // encoding, should be one of `base64`, `utf8`, `ascii`
690
- 'utf8',
691
- // should data append to existing content ?
692
- true
789
+ PATH_TO_FILE,
790
+ // encoding, should be one of `base64`, `utf8`, `ascii`
791
+ 'utf8',
792
+ // should data append to existing content ?
793
+ true
693
794
  )
694
- .then(ofstream => ofstream.write('foo'))
695
- .then(ofstream => ofstream.write('bar'))
696
- .then(ofstream => ofstream.write('foobar'))
697
- .then(ofstream => ofstream.close())
698
- .catch(console.error)
795
+ .then(ofstream => ofstream.write('foo'))
796
+ .then(ofstream => ofstream.write('bar'))
797
+ .then(ofstream => ofstream.write('foobar'))
798
+ .then(ofstream => ofstream.close())
799
+ .catch(console.error)
699
800
  ```
700
801
 
701
802
  or
702
803
 
703
804
  ```js
704
805
  ReactNativeBlobUtil.fs.writeStream(
705
- PATH_TO_FILE,
706
- // encoding, should be one of `base64`, `utf8`, `ascii`
707
- 'utf8',
708
- // should data append to existing content ?
709
- true
806
+ PATH_TO_FILE,
807
+ // encoding, should be one of `base64`, `utf8`, `ascii`
808
+ 'utf8',
809
+ // should data append to existing content ?
810
+ true
710
811
  )
711
- .then(stream => Promise.all([
712
- stream.write('foo'),
713
- stream.write('bar'),
714
- stream.write('foobar')
715
- ]))
716
- // Use array destructuring to get the stream object from the first item of the array we get from Promise.all()
717
- .then(([stream]) => stream.close())
718
- .catch(console.error)
812
+ .then(stream => Promise.all([
813
+ stream.write('foo'),
814
+ stream.write('bar'),
815
+ stream.write('foobar')
816
+ ]))
817
+ // Use array destructuring to get the stream object from the first item of the array we get from Promise.all()
818
+ .then(([stream]) => stream.close())
819
+ .catch(console.error)
719
820
  ```
720
821
 
721
822
  You should **NOT** do something like this:
722
823
 
723
824
  ```js
724
825
  ReactNativeBlobUtil.fs.writeStream(
725
- PATH_TO_FILE,
726
- // encoding, should be one of `base64`, `utf8`, `ascii`
727
- 'utf8',
728
- // should data append to existing content ?
729
- true)
730
- .then((ofstream) => {
731
- // BAD IDEA - Don't do this, those writes are unchecked:
732
- ofstream.write('foo')
733
- ofstream.write('bar')
734
- ofstream.close()
735
- })
736
- .catch(console.error) // Cannot catch any write() errors!
826
+ PATH_TO_FILE,
827
+ // encoding, should be one of `base64`, `utf8`, `ascii`
828
+ 'utf8',
829
+ // should data append to existing content ?
830
+ true)
831
+ .then((ofstream) => {
832
+ // BAD IDEA - Don't do this, those writes are unchecked:
833
+ ofstream.write('foo')
834
+ ofstream.write('bar')
835
+ ofstream.close()
836
+ })
837
+ .catch(console.error) // Cannot catch any write() errors!
737
838
  ```
738
839
 
739
- The problem with the above code is that the promises from the `ofstream.write()` calls are detached and "Lost".
740
- That means the entire promise chain A) resolves without waiting for the writes to finish and B) any errors caused by them are lost.
741
- That code may _seem_ to work if there are no errors, but those writes are of the type "fire and forget": You start them and then turn away and never know if they really succeeded.
840
+ The problem with the above code is that the promises from the `ofstream.write()` calls are detached and "Lost". That means the entire promise chain A) resolves without waiting for the writes to finish and B) any errors caused by them are lost. That code may _seem_ to work if there are no errors, but those writes are of the type "fire and forget": You start them and then turn away and never know if they really succeeded.
742
841
 
743
842
  ### Cache File Management
744
843
 
@@ -746,20 +845,20 @@ When using `fileCache` or `path` options along with `fetch` API, response data w
746
845
 
747
846
  ```js
748
847
 
749
- // remove file using ReactNativeBlobUtilResponse.flush() object method
750
- ReactNativeBlobUtil.config({
751
- fileCache : true
752
- })
753
- .fetch('GET', 'http://example.com/download/file')
754
- .then((res) => {
755
- // remove cached file from storage
756
- res.flush()
757
- })
758
-
759
- // remove file by specifying a path
760
- ReactNativeBlobUtil.fs.unlink('some-file-path').then(() => {
848
+ // remove file using ReactNativeBlobUtilResponse.flush() object method
849
+ ReactNativeBlobUtil.config({
850
+ fileCache: true
851
+ })
852
+ .fetch('GET', 'http://example.com/download/file')
853
+ .then((res) => {
854
+ // remove cached file from storage
855
+ res.flush()
856
+ })
857
+
858
+ // remove file by specifying a path
859
+ ReactNativeBlobUtil.fs.unlink('some-file-path').then(() => {
761
860
  // ...
762
- })
861
+ })
763
862
 
764
863
  ```
765
864
 
@@ -767,33 +866,34 @@ You can also group requests by using `session` API and use `dispose` to remove t
767
866
 
768
867
  ```js
769
868
 
770
- ReactNativeBlobUtil.config({
771
- fileCache : true
772
- })
773
- .fetch('GET', 'http://example.com/download/file')
774
- .then((res) => {
775
- // set session of a response
776
- res.session('foo')
777
- })
869
+ ReactNativeBlobUtil.config({
870
+ fileCache: true
871
+ })
872
+ .fetch('GET', 'http://example.com/download/file')
873
+ .then((res) => {
874
+ // set session of a response
875
+ res.session('foo')
876
+ })
778
877
 
779
- ReactNativeBlobUtil.config({
878
+ ReactNativeBlobUtil.config({
780
879
  // you can also set session beforehand
781
- session : 'foo'
782
- fileCache : true
783
- })
784
- .fetch('GET', 'http://example.com/download/file')
785
- .then((res) => {
786
- // ...
787
- })
788
-
789
- // or put an existing file path to the session
790
- ReactNativeBlobUtil.session('foo').add('some-file-path')
791
- // remove a file path from the session
792
- ReactNativeBlobUtil.session('foo').remove('some-file-path')
793
- // list paths of a session
794
- ReactNativeBlobUtil.session('foo').list()
795
- // remove all files in a session
796
- ReactNativeBlobUtil.session('foo').dispose().then(() => { ... })
880
+ session: 'foo'
881
+ fileCache: true
882
+ })
883
+ .fetch('GET', 'http://example.com/download/file')
884
+ .then((res) => {
885
+ // ...
886
+ })
887
+
888
+ // or put an existing file path to the session
889
+ ReactNativeBlobUtil.session('foo').add('some-file-path')
890
+ // remove a file path from the session
891
+ ReactNativeBlobUtil.session('foo').remove('some-file-path')
892
+ // list paths of a session
893
+ ReactNativeBlobUtil.session('foo').list()
894
+ // remove all files in a session
895
+ ReactNativeBlobUtil.session('foo').dispose().then(() => { ...
896
+ })
797
897
 
798
898
  ```
799
899
 
@@ -802,7 +902,7 @@ You can also group requests by using `session` API and use `dispose` to remove t
802
902
  After `0.9.4`, the `Chunked` transfer encoding is disabled by default due to some service provider may not support chunked transfer. To enable it, set `Transfer-Encoding` header to `Chunked`.
803
903
 
804
904
  ```js
805
- ReactNativeBlobUtil.fetch('POST', 'http://example.com/upload', { 'Transfer-Encoding' : 'Chunked' }, bodyData)
905
+ ReactNativeBlobUtil.fetch('POST', 'http://example.com/upload', {'Transfer-Encoding': 'Chunked'}, bodyData)
806
906
  ```
807
907
 
808
908
  ### Self-Signed SSL Server
@@ -811,44 +911,86 @@ By default, react-native-blob-util does NOT allow connection to unknown certific
811
911
 
812
912
  ```js
813
913
  ReactNativeBlobUtil.config({
814
- trusty : true
815
- })
816
- .fetch('GET', 'https://mysite.com')
817
- .then((resp) => {
818
- // ...
914
+ trusty: true
819
915
  })
916
+ .fetch('GET', 'https://mysite.com')
917
+ .then((resp) => {
918
+ // ...
919
+ })
820
920
  ```
821
921
 
822
922
  ### WiFi only requests
823
923
 
824
- If you wish to only route requests through the Wifi interface, set the below configuration.
825
- Note: On Android, the `ACCESS_NETWORK_STATE` permission must be set, and this flag will only work
826
- on API version 21 (Lollipop, Android 5.0) or above. APIs below 21 will ignore this flag.
924
+ If you wish to only route requests through the Wifi interface, set the below configuration. Note: On Android, the `ACCESS_NETWORK_STATE` permission must be set, and this flag will only work on API version 21 (Lollipop, Android 5.0) or above. APIs below 21 will ignore this flag.
827
925
 
828
926
  ```js
829
927
  ReactNativeBlobUtil.config({
830
- wifiOnly : true
831
- })
832
- .fetch('GET', 'https://mysite.com')
833
- .then((resp) => {
834
- // ...
928
+ wifiOnly: true
835
929
  })
930
+ .fetch('GET', 'https://mysite.com')
931
+ .then((resp) => {
932
+ // ...
933
+ })
836
934
  ```
837
935
 
936
+ ### Transform Files
937
+
938
+ Sometimes you may need the files to be transformed after reading from storage or before writing into storage (eg encryption/decyrption). In order to perform the transformations, use `readFileWithTransform` and `writeFileWithTransform`. NOTE: you must set a transformer on the file in order for the transformation to happen (see [Setting a File Transformer](#Setting-A-File-Transformer)).
939
+
838
940
  ## Web API Polyfills
839
941
 
840
- After `0.8.0` we've made some [Web API polyfills](https://github.com/joltup/react-native-blob-util/wiki/Web-API-Polyfills-(experimental)) that makes some browser-based library available in RN.
942
+ After `0.8.0` we've made some [Web API polyfills](https://github.com/RonRadtke/react-native-blob-util/wiki/Web-API-Polyfills-(experimental)) that makes some browser-based library available in RN.
841
943
 
842
944
  - Blob
843
945
  - XMLHttpRequest (Use our implementation if you're going to use it with Blob)
844
946
 
845
- Here's a [sample app](https://github.com/joltup/rn-firebase-storage-upload-sample) that uses polyfills to upload files to FireBase.
947
+
948
+ ## Setting A File Transformer
949
+
950
+ Setting a file transformer will allow you to specify how data should be transformed whenever the library is writing into storage or reading from storage. A use case for this is if you want the files handled by this library to be encrypted.
951
+
952
+ If you want to use a file transformer, you must implement an interface defined in:
953
+
954
+ [ReactNativeBlobUtilFileTransformer.h (iOS)](/ios/ReactNativeBlobUtilFileTransformer.h)
955
+
956
+ [ReactNativeBlobUtilFileTransformer.java (Android)](/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java)
957
+
958
+ Then you set the File Transformer during app startup
959
+
960
+ Android:
961
+ ```java
962
+ public class MainApplication extends Application implements ReactApplication {
963
+ ...
964
+ @Override
965
+ public void onCreate() {
966
+ ...
967
+ ReactNativeBlobUtilFileTransformer.sharedFileTransformer = new MyCustomEncryptor();
968
+ ...
969
+ }
970
+ ```
971
+
972
+ iOS:
973
+ ```m
974
+ @implementation AppDelegate
975
+ ...
976
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
977
+ {
978
+ ...
979
+ [ReactNativeBlobUtilFileTransformer setFileTransformer: MyCustomEncryptor.new];
980
+ ...
981
+ }
982
+ ```
983
+
984
+ Here are the places where the transformer would apply
985
+ - Reading a file from the file system
986
+ - Writing a file into the file system
987
+ - Http response is downloaded to storage directly
846
988
 
847
989
  ## Performance Tips
848
990
 
849
991
  **Read Stream and Progress Event Overhead**
850
992
 
851
- If the process seems to block JS thread when file is large when reading data via `fs.readStream`. It might because the default buffer size is quite small (4kb) which result in a lot of events triggered from JS thread. Try to increase the buffer size (for example 100kb = 102400) and set a larger interval (available for 0.9.4+, the default value is 10ms) to limit the frequency.
993
+ If the process seems to block JS thread when file is large when reading data via `fs.readStream`. It might because the default buffer size is quite small (4kb) which result in a lot of events triggered from JS thread. Try to increase the buffer size (for example 100kb = 102400) and set a larger interval (available for 0.9.4+, the default value is 10ms) to limit the frequency.
852
994
 
853
995
  **Reduce RCT Bridge and BASE64 Overhead**
854
996
 
@@ -871,18 +1013,17 @@ If you're going to concatenate files, you don't have to read the data to JS cont
871
1013
  ## Caveats
872
1014
 
873
1015
  * This library does not urlencode unicode characters in URL automatically, see [#146](https://github.com/wkh237/react-native-fetch-blob/issues/146).
874
- * When you create a `Blob` , from an existing file, the file **WILL BE REMOVED** if you `close` the blob.
1016
+ * When you create a `Blob` , from an existing file, the file **WILL BE REMOVED** if you `close` the blob.
875
1017
  * If you replaced `window.XMLHttpRequest` for some reason (e.g. make Firebase SDK work), it will also affect how official `fetch` works (basically it should work just fine).
876
- * When file stream and upload/download progress event slow down your app, consider an upgrade to `0.9.6+`, use [additional arguments](https://github.com/joltup/react-native-blob-util/wiki/Fetch-API#fetchprogressconfig-eventlistenerpromiseReactNativeBlobUtilresponse) to limit its frequency.
1018
+ * When file stream and upload/download progress event slow down your app, consider an upgrade to `0.9.6+`, use [additional arguments](https://github.com/RonRadtke/react-native-blob-util/wiki/Fetch-API#fetchprogressconfig-eventlistenerpromiseReactNativeBlobUtilresponse) to limit its frequency.
877
1019
  * When passing a file path to the library, remove `file://` prefix.
878
1020
 
879
- when you got a problem, have a look at [Trouble Shooting](https://github.com/joltup/react-native-blob-util/wiki/Trouble-Shooting) or [issues labeled Trouble Shooting](https://github.com/joltup/react-native-blob-util/issues?utf8=✓&q=label:%22trouble%20shooting%22%20), there'd be some helpful information.
1021
+ when you got a problem, have a look at [Trouble Shooting](https://github.com/RonRadtke/react-native-blob-util/wiki/Trouble-Shooting).
880
1022
 
881
1023
  ## Changes
882
1024
 
883
- See [release notes](https://github.com/joltup/react-native-blob-util/releases)
1025
+ See [release notes](https://github.com/RonRadtke/react-native-blob-util/releases)
884
1026
 
885
1027
  ### Development
886
1028
 
887
- If you're interested in hacking this module, check our [development guide](https://github.com/joltup/react-native-blob-util/wiki/Home), there might be some helpful information.
888
- Please feel free to make a PR or file an issue.
1029
+ If you're interested in hacking this module, check our [development guide](https://github.com/RonRadtke/react-native-blob-util/wiki/Home), there might be some helpful information. Please feel free to make a PR or file an issue.