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.
- package/README.md +542 -401
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +89 -25
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +14 -15
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +10 -6
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +115 -289
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java +10 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +314 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilPackage.java +6 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +46 -22
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilStream.java +287 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilUtils.java +57 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +9 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -0
- package/class/ReactNativeBlobUtilBlobResponse.js +1 -1
- package/fs.js +44 -4
- package/index.d.ts +121 -1
- package/index.js +2 -0
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +6 -4
- package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +6 -0
- package/ios/ReactNativeBlobUtilConst.h +1 -0
- package/ios/ReactNativeBlobUtilConst.m +1 -0
- package/ios/ReactNativeBlobUtilFS.h +3 -1
- package/ios/ReactNativeBlobUtilFS.m +33 -0
- package/ios/ReactNativeBlobUtilFileTransformer.h +24 -0
- package/ios/ReactNativeBlobUtilFileTransformer.m +21 -0
- package/ios/ReactNativeBlobUtilReqBuilder.m +2 -2
- package/ios/ReactNativeBlobUtilRequest.m +30 -1
- package/mediacollection.js +38 -0
- package/package.json +1 -1
- package/polyfill/Fetch.js +4 -2
- package/scripts/prelink.js +1 -1
- package/types.js +4 -0
package/README.md
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
# react-native-blob-util
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
[](https://github.com/RonRadtke/react-native-blob-util/releases) [](https://www.npmjs.com/package/react-native-blob-util)  [](https://github.com/RonRadtke/react-native-blob-util/wiki) []()
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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/
|
|
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
|
|
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/
|
|
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/
|
|
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
|
-
|
|
197
|
-
|
|
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
|
|
216
|
+
Authorization: 'Bearer access-token...',
|
|
213
217
|
// more headers ..
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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/
|
|
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
|
-
|
|
288
|
-
|
|
289
|
-
})
|
|
290
|
-
.fetch('GET', 'http://www.example.com/file/example.zip', {
|
|
291
|
-
|
|
292
|
-
})
|
|
293
|
-
.then((res) => {
|
|
294
|
-
|
|
295
|
-
|
|
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
|
-
|
|
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
|
|
333
|
+
Authorization: "Bearer access-token...",
|
|
309
334
|
'Dropbox-API-Arg': JSON.stringify({
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
335
|
+
path: '/img-from-react-native.png',
|
|
336
|
+
mode: 'add',
|
|
337
|
+
autorename: true,
|
|
338
|
+
mute: false
|
|
314
339
|
}),
|
|
315
|
-
'Content-Type'
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
|
360
|
+
Authorization: "Bearer access-token...",
|
|
336
361
|
'Dropbox-API-Arg': JSON.stringify({
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
362
|
+
path: '/img-from-react-native.png',
|
|
363
|
+
mode: 'add',
|
|
364
|
+
autorename: true,
|
|
365
|
+
mute: false
|
|
341
366
|
}),
|
|
342
|
-
'Content-Type'
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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
|
-
|
|
363
|
-
Authorization
|
|
364
|
-
otherHeader
|
|
365
|
-
'Content-Type'
|
|
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
|
-
{
|
|
393
|
+
{name: 'avatar', filename: 'avatar.png', data: binaryDataInBase64},
|
|
369
394
|
// custom content type
|
|
370
|
-
{
|
|
395
|
+
{name: 'avatar-png', filename: 'avatar-png.png', type: 'image/png', data: binaryDataInBase64},
|
|
371
396
|
// part file from storage
|
|
372
|
-
{
|
|
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
|
-
{
|
|
375
|
-
{
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
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
|
-
|
|
391
|
-
Authorization
|
|
392
|
-
otherHeader
|
|
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'
|
|
395
|
-
|
|
421
|
+
'Content-Type': 'multipart/form-data',
|
|
422
|
+
}, [
|
|
396
423
|
// append field data from file path
|
|
397
424
|
{
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
-
{
|
|
414
|
-
{
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
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
|
-
|
|
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
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
|
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
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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/
|
|
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
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
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
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
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
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
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
|
-
|
|
605
|
-
|
|
606
|
-
|
|
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/
|
|
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
|
-
|
|
626
|
-
- [
|
|
627
|
-
- [
|
|
628
|
-
- [
|
|
629
|
-
- [
|
|
630
|
-
-
|
|
631
|
-
- [
|
|
632
|
-
- [
|
|
633
|
-
-
|
|
634
|
-
- [
|
|
635
|
-
- [
|
|
636
|
-
- [
|
|
637
|
-
- [
|
|
638
|
-
- [
|
|
639
|
-
- [
|
|
640
|
-
- [
|
|
641
|
-
- [
|
|
642
|
-
- [
|
|
643
|
-
- [
|
|
644
|
-
- [
|
|
645
|
-
|
|
646
|
-
|
|
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
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
.then((ifstream) => {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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
|
-
|
|
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
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
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
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
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
|
-
|
|
713
|
-
|
|
714
|
-
|
|
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
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
.then((ofstream) => {
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
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
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
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
|
-
|
|
771
|
-
fileCache
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
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
|
-
|
|
878
|
+
ReactNativeBlobUtil.config({
|
|
780
879
|
// you can also set session beforehand
|
|
781
|
-
session
|
|
782
|
-
fileCache
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
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', {
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
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`.
|
|
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` ,
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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.
|