react-native-blob-util 0.13.17 → 0.14.1
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 +472 -407
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +85 -21
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +14 -15
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +8 -6
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +92 -292
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +299 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilPackage.java +6 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +17 -21
- 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 +5 -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/fs.js +2 -1
- package/index.d.ts +107 -2
- package/index.js +2 -0
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +2 -1
- package/ios/ReactNativeBlobUtilFS.h +1 -0
- package/ios/ReactNativeBlobUtilFS.m +4 -0
- package/ios/ReactNativeBlobUtilReqBuilder.m +1 -0
- package/mediacollection.js +33 -0
- package/package.json +1 -1
- package/scripts/prelink.js +1 -1
- package/types.js +3 -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,70 @@ 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
|
+
#### Upload example : Dropbox [files-upload](https://www.dropbox.com/developers/documentation/http/documentation#files-upload) API
|
|
302
307
|
|
|
303
308
|
`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
309
|
|
|
305
310
|
```js
|
|
306
311
|
|
|
307
312
|
ReactNativeBlobUtil.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
|
|
308
|
-
Authorization
|
|
313
|
+
Authorization: "Bearer access-token...",
|
|
309
314
|
'Dropbox-API-Arg': JSON.stringify({
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
315
|
+
path: '/img-from-react-native.png',
|
|
316
|
+
mode: 'add',
|
|
317
|
+
autorename: true,
|
|
318
|
+
mute: false
|
|
314
319
|
}),
|
|
315
|
-
'Content-Type'
|
|
320
|
+
'Content-Type': 'application/octet-stream',
|
|
316
321
|
// here's the body you're going to send, should be a BASE64 encoded string
|
|
317
322
|
// (you can use "base64"(refer to the library 'mathiasbynens/base64') APIs to make one).
|
|
318
323
|
// The data will be converted to "byte array"(say, blob) before request sent.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
324
|
+
}, base64ImageString)
|
|
325
|
+
.then((res) => {
|
|
326
|
+
console.log(res.text())
|
|
327
|
+
})
|
|
328
|
+
.catch((err) => {
|
|
329
|
+
// error handling ..
|
|
330
|
+
})
|
|
326
331
|
```
|
|
327
332
|
|
|
328
333
|
### Upload a file from storage
|
|
@@ -332,23 +337,23 @@ If you're going to use a `file` as request body, just wrap the path with `wrap`
|
|
|
332
337
|
```js
|
|
333
338
|
ReactNativeBlobUtil.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
|
|
334
339
|
// dropbox upload headers
|
|
335
|
-
Authorization
|
|
340
|
+
Authorization: "Bearer access-token...",
|
|
336
341
|
'Dropbox-API-Arg': JSON.stringify({
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
342
|
+
path: '/img-from-react-native.png',
|
|
343
|
+
mode: 'add',
|
|
344
|
+
autorename: true,
|
|
345
|
+
mute: false
|
|
341
346
|
}),
|
|
342
|
-
'Content-Type'
|
|
347
|
+
'Content-Type': 'application/octet-stream',
|
|
343
348
|
// Change BASE64 encoded data to a file path with prefix `ReactNativeBlobUtil-file://`.
|
|
344
349
|
// Or simply wrap the file path with ReactNativeBlobUtil.wrap().
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
}, ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE))
|
|
351
|
+
.then((res) => {
|
|
352
|
+
console.log(res.text())
|
|
353
|
+
})
|
|
354
|
+
.catch((err) => {
|
|
355
|
+
// error handling ..
|
|
356
|
+
})
|
|
352
357
|
```
|
|
353
358
|
|
|
354
359
|
### Multipart/form-data example: Post form data with file and data
|
|
@@ -359,67 +364,71 @@ Elements have property `filename` will be transformed into binary format, otherw
|
|
|
359
364
|
|
|
360
365
|
```js
|
|
361
366
|
|
|
362
|
-
|
|
363
|
-
Authorization
|
|
364
|
-
otherHeader
|
|
365
|
-
'Content-Type'
|
|
366
|
-
|
|
367
|
+
ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
|
|
368
|
+
Authorization: "Bearer access-token",
|
|
369
|
+
otherHeader: "foo",
|
|
370
|
+
'Content-Type': 'multipart/form-data',
|
|
371
|
+
}, [
|
|
367
372
|
// element with property `filename` will be transformed into `file` in form data
|
|
368
|
-
{
|
|
373
|
+
{name: 'avatar', filename: 'avatar.png', data: binaryDataInBase64},
|
|
369
374
|
// custom content type
|
|
370
|
-
{
|
|
375
|
+
{name: 'avatar-png', filename: 'avatar-png.png', type: 'image/png', data: binaryDataInBase64},
|
|
371
376
|
// part file from storage
|
|
372
|
-
{
|
|
377
|
+
{name: 'avatar-foo', filename: 'avatar-foo.png', type: 'image/foo', data: ReactNativeBlobUtil.wrap(path_to_a_file)},
|
|
373
378
|
// elements without property `filename` will be sent as plain text
|
|
374
|
-
{
|
|
375
|
-
{
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
379
|
+
{name: 'name', data: 'user'},
|
|
380
|
+
{
|
|
381
|
+
name: 'info', data: JSON.stringify({
|
|
382
|
+
mail: 'example@example.com',
|
|
383
|
+
tel: '12345678'
|
|
384
|
+
})
|
|
385
|
+
},
|
|
386
|
+
]).then((resp) => {
|
|
380
387
|
// ...
|
|
381
|
-
|
|
388
|
+
}).catch((err) => {
|
|
382
389
|
// ...
|
|
383
|
-
|
|
390
|
+
})
|
|
384
391
|
```
|
|
385
392
|
|
|
386
393
|
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
394
|
|
|
388
395
|
```js
|
|
389
396
|
|
|
390
|
-
|
|
391
|
-
Authorization
|
|
392
|
-
otherHeader
|
|
397
|
+
ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
|
|
398
|
+
Authorization: "Bearer access-token",
|
|
399
|
+
otherHeader: "foo",
|
|
393
400
|
// this is required, otherwise it won't be process as a multipart/form-data request
|
|
394
|
-
'Content-Type'
|
|
395
|
-
|
|
401
|
+
'Content-Type': 'multipart/form-data',
|
|
402
|
+
}, [
|
|
396
403
|
// append field data from file path
|
|
397
404
|
{
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
405
|
+
name: 'avatar',
|
|
406
|
+
filename: 'avatar.png',
|
|
407
|
+
// Change BASE64 encoded data to a file path with prefix `ReactNativeBlobUtil-file://`.
|
|
408
|
+
// Or simply wrap the file path with ReactNativeBlobUtil.wrap().
|
|
409
|
+
data: ReactNativeBlobUtil.wrap(PATH_TO_THE_FILE)
|
|
403
410
|
},
|
|
404
411
|
{
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
+
name: 'ringtone',
|
|
413
|
+
filename: 'ring.mp3',
|
|
414
|
+
// use custom MIME type
|
|
415
|
+
type: 'application/mp3',
|
|
416
|
+
// upload a file from asset is also possible in version >= 0.6.2
|
|
417
|
+
data: ReactNativeBlobUtil.wrap(ReactNativeBlobUtil.fs.asset('default-ringtone.mp3'))
|
|
418
|
+
},
|
|
412
419
|
// elements without property `filename` will be sent as plain text
|
|
413
|
-
{
|
|
414
|
-
{
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
420
|
+
{name: 'name', data: 'user'},
|
|
421
|
+
{
|
|
422
|
+
name: 'info', data: JSON.stringify({
|
|
423
|
+
mail: 'example@example.com',
|
|
424
|
+
tel: '12345678'
|
|
425
|
+
})
|
|
426
|
+
},
|
|
427
|
+
]).then((resp) => {
|
|
419
428
|
// ...
|
|
420
|
-
|
|
429
|
+
}).catch((err) => {
|
|
421
430
|
// ...
|
|
422
|
-
|
|
431
|
+
})
|
|
423
432
|
```
|
|
424
433
|
|
|
425
434
|
### Upload/Download progress
|
|
@@ -428,47 +437,46 @@ In `version >= 0.4.2` it is possible to know the upload/download progress. After
|
|
|
428
437
|
|
|
429
438
|
```js
|
|
430
439
|
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
|
-
|
|
448
|
-
```
|
|
449
|
-
|
|
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
|
-
|
|
440
|
+
//... some headers,
|
|
441
|
+
'Content-Type': 'octet-stream'
|
|
442
|
+
}, base64DataString)
|
|
443
|
+
// listen to upload progress event
|
|
444
|
+
.uploadProgress((written, total) => {
|
|
445
|
+
console.log('uploaded', written / total)
|
|
446
|
+
})
|
|
447
|
+
// listen to download progress event
|
|
448
|
+
.progress((received, total) => {
|
|
449
|
+
console.log('progress', received / total)
|
|
450
|
+
})
|
|
451
|
+
.then((resp) => {
|
|
452
|
+
// ...
|
|
453
|
+
})
|
|
454
|
+
.catch((err) => {
|
|
455
|
+
// ...
|
|
456
|
+
})
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
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
460
|
|
|
453
461
|
```js
|
|
454
462
|
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
|
-
|
|
463
|
+
//... some headers,
|
|
464
|
+
'Content-Type': 'octet-stream'
|
|
465
|
+
}, base64DataString)
|
|
466
|
+
// listen to upload progress event, emit every 250ms
|
|
467
|
+
.uploadProgress({interval: 250}, (written, total) => {
|
|
468
|
+
console.log('uploaded', written / total)
|
|
469
|
+
})
|
|
470
|
+
// listen to download progress event, every 10%
|
|
471
|
+
.progress({count: 10}, (received, total) => {
|
|
472
|
+
console.log('progress', received / total)
|
|
473
|
+
})
|
|
474
|
+
.then((resp) => {
|
|
475
|
+
// ...
|
|
476
|
+
})
|
|
477
|
+
.catch((err) => {
|
|
478
|
+
// ...
|
|
479
|
+
})
|
|
472
480
|
```
|
|
473
481
|
|
|
474
482
|
### Cancel Request
|
|
@@ -478,13 +486,15 @@ After `0.7.0` it is possible to cancel an HTTP request. Upon cancellation, it th
|
|
|
478
486
|
```js
|
|
479
487
|
let task = ReactNativeBlobUtil.fetch('GET', 'http://example.com/file/1')
|
|
480
488
|
|
|
481
|
-
task.then(() => { ...
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
489
|
+
task.then(() => { ...
|
|
490
|
+
})
|
|
491
|
+
// handle request cancelled rejection
|
|
492
|
+
.catch((err) => {
|
|
493
|
+
console.log(err)
|
|
494
|
+
})
|
|
486
495
|
// cancel the request, the callback function is optional
|
|
487
|
-
task.cancel((err) => { ...
|
|
496
|
+
task.cancel((err) => { ...
|
|
497
|
+
})
|
|
488
498
|
|
|
489
499
|
```
|
|
490
500
|
|
|
@@ -494,11 +504,11 @@ task.cancel((err) => { ... })
|
|
|
494
504
|
|
|
495
505
|
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
506
|
|
|
497
|
-
[See document and examples](https://github.com/
|
|
507
|
+
[See document and examples](https://github.com/RonRadtke/react-native-blob-util/wiki/Fetch-API#fetch-replacement)
|
|
498
508
|
|
|
499
509
|
### Android Media Scanner, and Download Manager Support
|
|
500
510
|
|
|
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`.
|
|
511
|
+
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
512
|
|
|
503
513
|
**Media Scanner**
|
|
504
514
|
|
|
@@ -507,18 +517,18 @@ Media scanner scans the file and categorizes by given MIME type, if MIME type no
|
|
|
507
517
|
```js
|
|
508
518
|
|
|
509
519
|
ReactNativeBlobUtil
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
520
|
+
.config({
|
|
521
|
+
// DCIMDir is in external storage
|
|
522
|
+
path: dirs.DCIMDir + '/music.mp3'
|
|
523
|
+
})
|
|
524
|
+
.fetch('GET', 'http://example.com/music.mp3')
|
|
525
|
+
.then((res) => ReactNativeBlobUtil.fs.scanFile([{path: res.path(), mime: 'audio/mpeg'}]))
|
|
526
|
+
.then(() => {
|
|
527
|
+
// scan file success
|
|
528
|
+
})
|
|
529
|
+
.catch((err) => {
|
|
530
|
+
// scan file error
|
|
531
|
+
})
|
|
522
532
|
```
|
|
523
533
|
|
|
524
534
|
**Download Manager**
|
|
@@ -533,22 +543,22 @@ When download complete, DownloadManager will generate a file path so that you ca
|
|
|
533
543
|
|
|
534
544
|
```js
|
|
535
545
|
ReactNativeBlobUtil
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
546
|
+
.config({
|
|
547
|
+
addAndroidDownloads: {
|
|
548
|
+
useDownloadManager: true, // <-- this is the only thing required
|
|
549
|
+
// Optional, override notification setting (default to true)
|
|
550
|
+
notification: false,
|
|
551
|
+
// Optional, but recommended since android DownloadManager will fail when
|
|
552
|
+
// the url does not contains a file extension, by default the mime type will be text/plain
|
|
553
|
+
mime: 'text/plain',
|
|
554
|
+
description: 'File downloaded by download manager.'
|
|
555
|
+
}
|
|
556
|
+
})
|
|
557
|
+
.fetch('GET', 'http://example.com/file/somefile')
|
|
558
|
+
.then((resp) => {
|
|
559
|
+
// the path of downloaded file
|
|
560
|
+
resp.path()
|
|
561
|
+
})
|
|
552
562
|
```
|
|
553
563
|
|
|
554
564
|
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 +573,22 @@ If you need to display a notification upon the file is downloaded to storage (as
|
|
|
563
573
|
|
|
564
574
|
```js
|
|
565
575
|
ReactNativeBlobUtil.config({
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
576
|
+
fileCache: true,
|
|
577
|
+
// android only options, these options be a no-op on IOS
|
|
578
|
+
addAndroidDownloads: {
|
|
579
|
+
// Show notification when response data transmitted
|
|
580
|
+
notification: true,
|
|
581
|
+
// Title of download notification
|
|
582
|
+
title: 'Great ! Download Success ! :O ',
|
|
583
|
+
// File description (not notification description)
|
|
584
|
+
description: 'An image file.',
|
|
585
|
+
mime: 'image/png',
|
|
586
|
+
// Make the file scannable by media scanner
|
|
587
|
+
mediaScannable: true,
|
|
588
|
+
}
|
|
579
589
|
})
|
|
580
|
-
.fetch('GET', 'http://example.com/image1.png')
|
|
581
|
-
.then(...)
|
|
590
|
+
.fetch('GET', 'http://example.com/image1.png')
|
|
591
|
+
.then(...)
|
|
582
592
|
```
|
|
583
593
|
|
|
584
594
|
**Open Downloaded File with Intent**
|
|
@@ -592,19 +602,19 @@ Download and install an APK programmatically
|
|
|
592
602
|
const android = ReactNativeBlobUtil.android
|
|
593
603
|
|
|
594
604
|
ReactNativeBlobUtil.config({
|
|
595
|
-
addAndroidDownloads
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
605
|
+
addAndroidDownloads: {
|
|
606
|
+
useDownloadManager: true,
|
|
607
|
+
title: 'awesome.apk',
|
|
608
|
+
description: 'An APK that will be installed',
|
|
609
|
+
mime: 'application/vnd.android.package-archive',
|
|
610
|
+
mediaScannable: true,
|
|
611
|
+
notification: true,
|
|
602
612
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
613
|
+
})
|
|
614
|
+
.fetch('GET', `http://www.example.com/awesome.apk`)
|
|
615
|
+
.then((res) => {
|
|
616
|
+
android.actionViewIntent(res.path(), 'application/vnd.android.package-archive')
|
|
617
|
+
})
|
|
608
618
|
```
|
|
609
619
|
|
|
610
620
|
Or show an image in image viewer
|
|
@@ -615,35 +625,96 @@ Or show an image in image viewer
|
|
|
615
625
|
|
|
616
626
|
## File System
|
|
617
627
|
|
|
628
|
+
### Android Media Storage
|
|
629
|
+
|
|
630
|
+
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.
|
|
631
|
+
|
|
632
|
+
#### CopyToMediaStore
|
|
633
|
+
|
|
634
|
+
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
|
|
635
|
+
|
|
636
|
+
```js
|
|
637
|
+
ReactNativeBlobUtil
|
|
638
|
+
.config({
|
|
639
|
+
fileCache: true
|
|
640
|
+
})
|
|
641
|
+
.fetch('GET', 'https://example.de/image.png', {'Accept': 'application/octet-stream'}, JSON.stringify(dat))
|
|
642
|
+
.then(async (res) => {
|
|
643
|
+
let result = await ReactNativeBlobUtil.MediaCollection.copyToMediaStore({
|
|
644
|
+
name: filename, // name of the file
|
|
645
|
+
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
|
|
646
|
+
mimeType: 'image/png' // MIME type of the file
|
|
647
|
+
},
|
|
648
|
+
'Download', // Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download")
|
|
649
|
+
res.path() // Path to the file being copied in the apps own storage
|
|
650
|
+
);
|
|
651
|
+
});
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
This example is taking advantage of the fileCache option to directly store the downloaded file and get a path for. <br>
|
|
655
|
+
Currently it's not possible to write data directly from a string recevied by fetch, but only to copy it from a file.
|
|
656
|
+
|
|
657
|
+
#### createMediaFile
|
|
658
|
+
|
|
659
|
+
Creates a new file in the specified collection without writing any data
|
|
660
|
+
|
|
661
|
+
````js
|
|
662
|
+
let path = await ReactNativeBlobUtil.MediaCollection.createMediafile({
|
|
663
|
+
name: filename, // name of the file
|
|
664
|
+
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
|
|
665
|
+
mimeType: 'image/png' // MIME type of the file
|
|
666
|
+
}, 'Download'// Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download")
|
|
667
|
+
);
|
|
668
|
+
````
|
|
669
|
+
|
|
670
|
+
#### writeMediaFile
|
|
671
|
+
|
|
672
|
+
Writes data from a file in the apps storage to an existing entry of the Media Store
|
|
673
|
+
````js
|
|
674
|
+
await ReactNativeBlobUtil.MediaCollection.writeToMediafile('content://....', // content uri of the entry in the media storage
|
|
675
|
+
localpath // path to the file that should be copied
|
|
676
|
+
);
|
|
677
|
+
````
|
|
678
|
+
|
|
679
|
+
#### copyToInternal
|
|
680
|
+
Copies an entry form the media storage to the apps internal storage.
|
|
681
|
+
````js
|
|
682
|
+
let destpath = ReactNativeBlobUtil.dirs.CacheDir + '/image.png';
|
|
683
|
+
await ReactNativeBlobUtil.MediaCollection.copyToInternal('content://....', // content uri of the entry in the media storage
|
|
684
|
+
destpath // path to destination the entry should be copied to
|
|
685
|
+
);
|
|
686
|
+
````
|
|
687
|
+
|
|
618
688
|
### File Access
|
|
619
689
|
|
|
620
690
|
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
691
|
|
|
622
|
-
Before start using file APIs, we recommend read [Differences between File Source](https://github.com/
|
|
692
|
+
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
693
|
|
|
624
694
|
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
|
-
|
|
695
|
+
|
|
696
|
+
- [asset (0.6.2)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#assetfilenamestringstring)
|
|
697
|
+
- [dirs](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#dirs)
|
|
698
|
+
- [createFile](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#createfilepath-data-encodingpromise)
|
|
699
|
+
- [writeFile (0.6.0)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#writefilepathstring-contentstring--array-encodingstring-appendbooleanpromise)
|
|
700
|
+
- [appendFile (0.6.0) ](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#appendfilepathstring-contentstring--arraynumber-encodingstring-promisenumber)
|
|
701
|
+
- [readFile (0.6.0)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#readfilepath-encodingpromise)
|
|
702
|
+
- [readStream](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#readstreampath-encoding-buffersize-interval-promisernfbreadstream)
|
|
703
|
+
- [hash (0.10.9)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithm-promise)
|
|
704
|
+
- [writeStream](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#writestreampathstring-encodingstringpromise)
|
|
705
|
+
- [hash](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithmpromise)
|
|
706
|
+
- [unlink](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#unlinkpathstringpromise)
|
|
707
|
+
- [mkdir](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#mkdirpathstringpromise)
|
|
708
|
+
- [ls](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#lspathstringpromise)
|
|
709
|
+
- [mv](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#mvfromstring-tostringpromise)
|
|
710
|
+
- [cp](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#cpsrcstring-deststringpromise)
|
|
711
|
+
- [exists](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#existspathstringpromise)
|
|
712
|
+
- [isDir](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#isdirpathstringpromise)
|
|
713
|
+
- [stat](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#statpathstringpromise)
|
|
714
|
+
- [lstat](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#lstatpathstringpromise)
|
|
715
|
+
- [scanFile (Android only)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#scanfilepathstringpromise-androi-only)
|
|
716
|
+
|
|
717
|
+
See [File API](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API) for more information
|
|
647
718
|
|
|
648
719
|
### File Stream
|
|
649
720
|
|
|
@@ -651,32 +722,32 @@ In `v0.5.0` we've added `writeStream` and `readStream`, which allows your app r
|
|
|
651
722
|
|
|
652
723
|
When calling `readStream` method, you have to `open` the stream, and start to read data. When the file is large, consider using an appropriate `bufferSize` and `interval` to reduce the native event dispatching overhead (see [Performance Tips](#user-content-performance-tips))
|
|
653
724
|
|
|
654
|
-
> The file stream event has a default throttle(10ms) and buffer size which preventing it cause too much overhead to main thread,
|
|
725
|
+
> The file stream event has a default throttle(10ms) and buffer size which preventing it cause too much overhead to main thread, you can also [tweak these values](#user-content-performance-tips).
|
|
655
726
|
|
|
656
727
|
```js
|
|
657
728
|
let data = ''
|
|
658
729
|
ReactNativeBlobUtil.fs.readStream(
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
.then((ifstream) => {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
730
|
+
// file path
|
|
731
|
+
PATH_TO_THE_FILE,
|
|
732
|
+
// encoding, should be one of `base64`, `utf8`, `ascii`
|
|
733
|
+
'base64',
|
|
734
|
+
// (optional) buffer size, default to 4096 (4095 for BASE64 encoded data)
|
|
735
|
+
// when reading file in BASE64 encoding, buffer size must be multiples of 3.
|
|
736
|
+
4095)
|
|
737
|
+
.then((ifstream) => {
|
|
738
|
+
ifstream.open()
|
|
739
|
+
ifstream.onData((chunk) => {
|
|
740
|
+
// when encoding is `ascii`, chunk will be an array contains numbers
|
|
741
|
+
// otherwise it will be a string
|
|
742
|
+
data += chunk
|
|
743
|
+
})
|
|
744
|
+
ifstream.onError((err) => {
|
|
745
|
+
console.log('oops', err)
|
|
746
|
+
})
|
|
747
|
+
ifstream.onEnd(() => {
|
|
748
|
+
<Image source={{uri: 'data:image/png,base64' + data}}
|
|
675
749
|
})
|
|
676
|
-
|
|
677
|
-
<Image source={{ uri : 'data:image/png,base64' + data }}
|
|
678
|
-
})
|
|
679
|
-
})
|
|
750
|
+
})
|
|
680
751
|
```
|
|
681
752
|
|
|
682
753
|
When using `writeStream`, the stream object becomes writable, and you can then perform operations like `write` and `close`.
|
|
@@ -685,60 +756,58 @@ Since version 0.10.9 `write()` resolves with the `ReactNativeBlobUtil` instance
|
|
|
685
756
|
|
|
686
757
|
```js
|
|
687
758
|
ReactNativeBlobUtil.fs.writeStream(
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
759
|
+
PATH_TO_FILE,
|
|
760
|
+
// encoding, should be one of `base64`, `utf8`, `ascii`
|
|
761
|
+
'utf8',
|
|
762
|
+
// should data append to existing content ?
|
|
763
|
+
true
|
|
693
764
|
)
|
|
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)
|
|
765
|
+
.then(ofstream => ofstream.write('foo'))
|
|
766
|
+
.then(ofstream => ofstream.write('bar'))
|
|
767
|
+
.then(ofstream => ofstream.write('foobar'))
|
|
768
|
+
.then(ofstream => ofstream.close())
|
|
769
|
+
.catch(console.error)
|
|
699
770
|
```
|
|
700
771
|
|
|
701
772
|
or
|
|
702
773
|
|
|
703
774
|
```js
|
|
704
775
|
ReactNativeBlobUtil.fs.writeStream(
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
776
|
+
PATH_TO_FILE,
|
|
777
|
+
// encoding, should be one of `base64`, `utf8`, `ascii`
|
|
778
|
+
'utf8',
|
|
779
|
+
// should data append to existing content ?
|
|
780
|
+
true
|
|
710
781
|
)
|
|
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)
|
|
782
|
+
.then(stream => Promise.all([
|
|
783
|
+
stream.write('foo'),
|
|
784
|
+
stream.write('bar'),
|
|
785
|
+
stream.write('foobar')
|
|
786
|
+
]))
|
|
787
|
+
// Use array destructuring to get the stream object from the first item of the array we get from Promise.all()
|
|
788
|
+
.then(([stream]) => stream.close())
|
|
789
|
+
.catch(console.error)
|
|
719
790
|
```
|
|
720
791
|
|
|
721
792
|
You should **NOT** do something like this:
|
|
722
793
|
|
|
723
794
|
```js
|
|
724
795
|
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!
|
|
737
|
-
```
|
|
738
|
-
|
|
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.
|
|
796
|
+
PATH_TO_FILE,
|
|
797
|
+
// encoding, should be one of `base64`, `utf8`, `ascii`
|
|
798
|
+
'utf8',
|
|
799
|
+
// should data append to existing content ?
|
|
800
|
+
true)
|
|
801
|
+
.then((ofstream) => {
|
|
802
|
+
// BAD IDEA - Don't do this, those writes are unchecked:
|
|
803
|
+
ofstream.write('foo')
|
|
804
|
+
ofstream.write('bar')
|
|
805
|
+
ofstream.close()
|
|
806
|
+
})
|
|
807
|
+
.catch(console.error) // Cannot catch any write() errors!
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
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
811
|
|
|
743
812
|
### Cache File Management
|
|
744
813
|
|
|
@@ -746,20 +815,20 @@ When using `fileCache` or `path` options along with `fetch` API, response data w
|
|
|
746
815
|
|
|
747
816
|
```js
|
|
748
817
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
818
|
+
// remove file using ReactNativeBlobUtilResponse.flush() object method
|
|
819
|
+
ReactNativeBlobUtil.config({
|
|
820
|
+
fileCache: true
|
|
821
|
+
})
|
|
822
|
+
.fetch('GET', 'http://example.com/download/file')
|
|
823
|
+
.then((res) => {
|
|
824
|
+
// remove cached file from storage
|
|
825
|
+
res.flush()
|
|
826
|
+
})
|
|
827
|
+
|
|
828
|
+
// remove file by specifying a path
|
|
829
|
+
ReactNativeBlobUtil.fs.unlink('some-file-path').then(() => {
|
|
761
830
|
// ...
|
|
762
|
-
|
|
831
|
+
})
|
|
763
832
|
|
|
764
833
|
```
|
|
765
834
|
|
|
@@ -767,33 +836,34 @@ You can also group requests by using `session` API and use `dispose` to remove t
|
|
|
767
836
|
|
|
768
837
|
```js
|
|
769
838
|
|
|
770
|
-
|
|
771
|
-
fileCache
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
839
|
+
ReactNativeBlobUtil.config({
|
|
840
|
+
fileCache: true
|
|
841
|
+
})
|
|
842
|
+
.fetch('GET', 'http://example.com/download/file')
|
|
843
|
+
.then((res) => {
|
|
844
|
+
// set session of a response
|
|
845
|
+
res.session('foo')
|
|
846
|
+
})
|
|
778
847
|
|
|
779
|
-
|
|
848
|
+
ReactNativeBlobUtil.config({
|
|
780
849
|
// you can also set session beforehand
|
|
781
|
-
session
|
|
782
|
-
fileCache
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
850
|
+
session: 'foo'
|
|
851
|
+
fileCache: true
|
|
852
|
+
})
|
|
853
|
+
.fetch('GET', 'http://example.com/download/file')
|
|
854
|
+
.then((res) => {
|
|
855
|
+
// ...
|
|
856
|
+
})
|
|
857
|
+
|
|
858
|
+
// or put an existing file path to the session
|
|
859
|
+
ReactNativeBlobUtil.session('foo').add('some-file-path')
|
|
860
|
+
// remove a file path from the session
|
|
861
|
+
ReactNativeBlobUtil.session('foo').remove('some-file-path')
|
|
862
|
+
// list paths of a session
|
|
863
|
+
ReactNativeBlobUtil.session('foo').list()
|
|
864
|
+
// remove all files in a session
|
|
865
|
+
ReactNativeBlobUtil.session('foo').dispose().then(() => { ...
|
|
866
|
+
})
|
|
797
867
|
|
|
798
868
|
```
|
|
799
869
|
|
|
@@ -802,7 +872,7 @@ You can also group requests by using `session` API and use `dispose` to remove t
|
|
|
802
872
|
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
873
|
|
|
804
874
|
```js
|
|
805
|
-
ReactNativeBlobUtil.fetch('POST', 'http://example.com/upload', {
|
|
875
|
+
ReactNativeBlobUtil.fetch('POST', 'http://example.com/upload', {'Transfer-Encoding': 'Chunked'}, bodyData)
|
|
806
876
|
```
|
|
807
877
|
|
|
808
878
|
### Self-Signed SSL Server
|
|
@@ -811,44 +881,40 @@ By default, react-native-blob-util does NOT allow connection to unknown certific
|
|
|
811
881
|
|
|
812
882
|
```js
|
|
813
883
|
ReactNativeBlobUtil.config({
|
|
814
|
-
|
|
815
|
-
})
|
|
816
|
-
.fetch('GET', 'https://mysite.com')
|
|
817
|
-
.then((resp) => {
|
|
818
|
-
// ...
|
|
884
|
+
trusty: true
|
|
819
885
|
})
|
|
886
|
+
.fetch('GET', 'https://mysite.com')
|
|
887
|
+
.then((resp) => {
|
|
888
|
+
// ...
|
|
889
|
+
})
|
|
820
890
|
```
|
|
821
891
|
|
|
822
892
|
### WiFi only requests
|
|
823
893
|
|
|
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.
|
|
894
|
+
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
895
|
|
|
828
896
|
```js
|
|
829
897
|
ReactNativeBlobUtil.config({
|
|
830
|
-
|
|
831
|
-
})
|
|
832
|
-
.fetch('GET', 'https://mysite.com')
|
|
833
|
-
.then((resp) => {
|
|
834
|
-
// ...
|
|
898
|
+
wifiOnly: true
|
|
835
899
|
})
|
|
900
|
+
.fetch('GET', 'https://mysite.com')
|
|
901
|
+
.then((resp) => {
|
|
902
|
+
// ...
|
|
903
|
+
})
|
|
836
904
|
```
|
|
837
905
|
|
|
838
906
|
## Web API Polyfills
|
|
839
907
|
|
|
840
|
-
After `0.8.0` we've made some [Web API polyfills](https://github.com/
|
|
908
|
+
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
909
|
|
|
842
910
|
- Blob
|
|
843
911
|
- XMLHttpRequest (Use our implementation if you're going to use it with Blob)
|
|
844
912
|
|
|
845
|
-
Here's a [sample app](https://github.com/joltup/rn-firebase-storage-upload-sample) that uses polyfills to upload files to FireBase.
|
|
846
|
-
|
|
847
913
|
## Performance Tips
|
|
848
914
|
|
|
849
915
|
**Read Stream and Progress Event Overhead**
|
|
850
916
|
|
|
851
|
-
If the process seems to block JS thread when file is large when reading data via `fs.readStream`.
|
|
917
|
+
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
918
|
|
|
853
919
|
**Reduce RCT Bridge and BASE64 Overhead**
|
|
854
920
|
|
|
@@ -871,18 +937,17 @@ If you're going to concatenate files, you don't have to read the data to JS cont
|
|
|
871
937
|
## Caveats
|
|
872
938
|
|
|
873
939
|
* 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` ,
|
|
940
|
+
* When you create a `Blob` , from an existing file, the file **WILL BE REMOVED** if you `close` the blob.
|
|
875
941
|
* 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/
|
|
942
|
+
* 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
943
|
* When passing a file path to the library, remove `file://` prefix.
|
|
878
944
|
|
|
879
|
-
when you got a problem, have a look at [Trouble Shooting](https://github.com/
|
|
945
|
+
when you got a problem, have a look at [Trouble Shooting](https://github.com/RonRadtke/react-native-blob-util/wiki/Trouble-Shooting).
|
|
880
946
|
|
|
881
947
|
## Changes
|
|
882
948
|
|
|
883
|
-
See [release notes](https://github.com/
|
|
949
|
+
See [release notes](https://github.com/RonRadtke/react-native-blob-util/releases)
|
|
884
950
|
|
|
885
951
|
### Development
|
|
886
952
|
|
|
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.
|
|
953
|
+
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.
|