Procházet zdrojové kódy

Merge pull request #497 from cristianoccazinsp/wifiOnly

wifi only option, and missing typings.
Travis Nuttall před 5 roky
rodič
revize
84d5312a72
No account linked to committer's email address

+ 35
- 11
README.md Zobrazit soubor

@@ -41,7 +41,7 @@ rn-fetch-blob version 0.10.16 is only compatible with react native 0.60 and up.
41 41
 
42 42
 ## About
43 43
 
44
-This project was started in the cause of solving issue [facebook/react-native#854](https://github.com/facebook/react-native/issues/854), React Native's lacks of `Blob` implementation which results into problems when transferring binary data. 
44
+This project was started in the cause of solving issue [facebook/react-native#854](https://github.com/facebook/react-native/issues/854), React Native's lacks of `Blob` implementation which results into problems when transferring binary data.
45 45
 
46 46
 It is committed to making file access and transfer easier and more efficient for React Native developers. We've implemented highly customizable filesystem and network module which plays well together. For example, developers can upload and download data directly from/to storage, which is more efficient, especially for large files. The file system supports file stream, so you don't have to worry about OOM problem when accessing large files.
47 47
 
@@ -116,8 +116,8 @@ If you're going to access external storage (say, SD card storage) for `Android 5
116 116
 
117 117
     <uses-permission android:name="android.permission.INTERNET" />
118 118
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
119
-+   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />                                               
120
-+   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />                                              
119
++   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
120
++   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
121 121
 +   <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
122 122
     ...
123 123
 
@@ -129,10 +129,18 @@ Also, if you're going to use `Android Download Manager` you have to add this to
129 129
     <intent-filter>
130 130
             <action android:name="android.intent.action.MAIN" />
131 131
             <category android:name="android.intent.category.LAUNCHER" />
132
-+           <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>                          
132
++           <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
133 133
     </intent-filter>
134 134
 ```
135 135
 
136
+If you are going to use the `wifiOnly` flag, you need to add this to `AndroidManifest.xml`
137
+
138
+```diff
139
++   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
140
+    ...
141
+
142
+```
143
+
136 144
 **Grant Access Permission for Android 6.0**
137 145
 
138 146
 Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. So adding permissions in `AndroidManifest.xml` won't work for Android 6.0+ devices. To grant permissions in runtime, you might use [PermissionAndroid API](https://facebook.github.io/react-native/docs/permissionsandroid.html).
@@ -168,7 +176,7 @@ To sum up:
168 176
 
169 177
 - 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.
170 178
 - To send binary data, you have two choices, use BASE64 encoded string or path points to a file contains the body.
171
- - 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.   
179
+ - 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.
172 180
  - Otherwise, if a string starts with `RNFetchBlob-file://` (which can simply be done by `RNFetchBlob.wrap(PATH_TO_THE_FILE)`), it will try to find the data from the URI string after `RNFetchBlob-file://` and use it as the request body.
173 181
 - To send the body as-is, simply use a `Content-Type` header not containing `;BASE64` or `application/octet`.
174 182
 
@@ -189,7 +197,7 @@ RNFetchBlob.fetch('GET', 'http://www.example.com/images/img1.png', {
189 197
   })
190 198
   .then((res) => {
191 199
     let status = res.info().status;
192
-    
200
+
193 201
     if(status == 200) {
194 202
       // the conversion is done in native code
195 203
       let base64Str = res.base64()
@@ -290,7 +298,7 @@ RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
290 298
     'Content-Type' : 'application/octet-stream',
291 299
     // here's the body you're going to send, should be a BASE64 encoded string
292 300
     // (you can use "base64"(refer to the library 'mathiasbynens/base64') APIs to make one).
293
-    // The data will be converted to "byte array"(say, blob) before request sent.  
301
+    // The data will be converted to "byte array"(say, blob) before request sent.
294 302
   }, base64ImageString)
295 303
   .then((res) => {
296 304
     console.log(res.text())
@@ -648,7 +656,7 @@ RNFetchBlob.fs.readStream(
648 656
     ifstream.onError((err) => {
649 657
       console.log('oops', err)
650 658
     })
651
-    ifstream.onEnd(() => {  
659
+    ifstream.onEnd(() => {
652 660
       <Image source={{ uri : 'data:image/png,base64' + data }}
653 661
     })
654 662
 })
@@ -673,7 +681,7 @@ RNFetchBlob.fs.writeStream(
673 681
 .catch(console.error)
674 682
 ```
675 683
 
676
-or 
684
+or
677 685
 
678 686
 ```js
679 687
 RNFetchBlob.fs.writeStream(
@@ -749,7 +757,7 @@ You can also group requests by using `session` API and use `dispose` to remove t
749 757
   .then((res) => {
750 758
     // set session of a response
751 759
     res.session('foo')
752
-  })  
760
+  })
753 761
 
754 762
   RNFetchblob.config({
755 763
     // you can also set session beforehand
@@ -759,7 +767,7 @@ You can also group requests by using `session` API and use `dispose` to remove t
759 767
   .fetch('GET', 'http://example.com/download/file')
760 768
   .then((res) => {
761 769
     // ...
762
-  })  
770
+  })
763 771
 
764 772
   // or put an existing file path to the session
765 773
   RNFetchBlob.session('foo').add('some-file-path')
@@ -794,6 +802,22 @@ RNFetchBlob.config({
794 802
 })
795 803
 ```
796 804
 
805
+### WiFi only requests
806
+
807
+If you wish to only route requests through the Wifi interface, set the below configuration.
808
+Note: On Android, the `ACCESS_NETWORK_STATE` permission must be set, and this flag will only work
809
+on API version 21 (Lollipop, Android 5.0) or above. APIs below 21 will ignore this flag.
810
+
811
+```js
812
+RNFetchBlob.config({
813
+  wifiOnly : true
814
+})
815
+.fetch('GET', 'https://mysite.com')
816
+.then((resp) => {
817
+  // ...
818
+})
819
+```
820
+
797 821
 ## Web API Polyfills
798 822
 
799 823
 After `0.8.0` we've made some [Web API polyfills](https://github.com/joltup/rn-fetch-blob/wiki/Web-API-Polyfills-(experimental)) that makes some browser-based library available in RN.

+ 2
- 0
android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java Zobrazit soubor

@@ -10,6 +10,7 @@ class RNFetchBlobConfig {
10 10
     public String appendExt;
11 11
     public ReadableMap addAndroidDownloads;
12 12
     public Boolean trusty;
13
+    public Boolean wifiOnly = false;
13 14
     public String key;
14 15
     public String mime;
15 16
     public Boolean auto;
@@ -26,6 +27,7 @@ class RNFetchBlobConfig {
26 27
         this.path = options.hasKey("path") ? options.getString("path") : null;
27 28
         this.appendExt = options.hasKey("appendExt") ? options.getString("appendExt") : "";
28 29
         this.trusty = options.hasKey("trusty") ? options.getBoolean("trusty") : false;
30
+        this.wifiOnly = options.hasKey("wifiOnly") ? options.getBoolean("wifiOnly") : false;
29 31
         if(options.hasKey("addAndroidDownloads")) {
30 32
             this.addAndroidDownloads = options.getMap("addAndroidDownloads");
31 33
         }

+ 54
- 5
android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java Zobrazit soubor

@@ -9,6 +9,10 @@ import android.database.Cursor;
9 9
 import android.net.Uri;
10 10
 import android.os.Build;
11 11
 import androidx.annotation.NonNull;
12
+import android.net.Network;
13
+import android.net.NetworkInfo;
14
+import android.net.NetworkCapabilities;
15
+import android.net.ConnectivityManager;
12 16
 import android.util.Base64;
13 17
 
14 18
 import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
@@ -36,6 +40,7 @@ import java.net.MalformedURLException;
36 40
 import java.net.SocketException;
37 41
 import java.net.SocketTimeoutException;
38 42
 import java.net.URL;
43
+import java.net.Proxy;
39 44
 import java.nio.ByteBuffer;
40 45
 import java.nio.charset.CharacterCodingException;
41 46
 import java.nio.charset.Charset;
@@ -231,6 +236,49 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
231 236
                 clientBuilder = client.newBuilder();
232 237
             }
233 238
 
239
+            // wifi only, need ACCESS_NETWORK_STATE permission
240
+            // and API level >= 21
241
+            if(this.options.wifiOnly){
242
+
243
+                boolean found = false;
244
+
245
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
246
+                    ConnectivityManager connectivityManager = (ConnectivityManager) RNFetchBlob.RCTContext.getSystemService(RNFetchBlob.RCTContext.CONNECTIVITY_SERVICE);
247
+                    Network[] networks = connectivityManager.getAllNetworks();
248
+
249
+                    for (Network network : networks) {
250
+
251
+                        NetworkInfo netInfo = connectivityManager.getNetworkInfo(network);
252
+                        NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(network);
253
+
254
+                        if(caps == null || netInfo == null){
255
+                            continue;
256
+                        }
257
+
258
+                        if(!netInfo.isConnected()){
259
+                            continue;
260
+                        }
261
+
262
+                        if(caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)){
263
+                            clientBuilder.proxy(Proxy.NO_PROXY);
264
+                            clientBuilder.socketFactory(network.getSocketFactory());
265
+                            found = true;
266
+                            break;
267
+
268
+                        }
269
+                    }
270
+
271
+                    if(!found){
272
+                        callback.invoke("No available WiFi connections.", null, null);
273
+                        releaseTaskResource();
274
+                        return;
275
+                    }
276
+                }
277
+                else{
278
+                    RNFetchBlobUtils.emitWarningEvent("RNFetchBlob: wifiOnly was set, but SDK < 21. wifiOnly was ignored.");
279
+                }
280
+            }
281
+
234 282
             final Request.Builder builder = new Request.Builder();
235 283
             try {
236 284
                 builder.url(new URL(url));
@@ -378,7 +426,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
378 426
                     }
379 427
                     catch (SocketTimeoutException e ){
380 428
                         timeout = true;
381
-                        RNFetchBlobUtils.emitWarningEvent("RNFetchBlob error when sending request : " + e.getLocalizedMessage());
429
+                        //RNFetchBlobUtils.emitWarningEvent("RNFetchBlob error when sending request : " + e.getLocalizedMessage());
382 430
                     } catch(Exception ex) {
383 431
 
384 432
                     }
@@ -414,7 +462,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
414 462
                     // check if this error caused by socket timeout
415 463
                     if(e.getClass().equals(SocketTimeoutException.class)) {
416 464
                         respInfo.putBoolean("timeout", true);
417
-                        callback.invoke("request timed out.", null, null);
465
+                        callback.invoke("The request timed out.", null, null);
418 466
                     }
419 467
                     else
420 468
                         callback.invoke(e.getLocalizedMessage(), null, null);
@@ -545,13 +593,14 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
545 593
 
546 594
                 RNFetchBlobFileResp rnFetchBlobFileResp = (RNFetchBlobFileResp) responseBody;
547 595
 
548
-                if(rnFetchBlobFileResp != null && rnFetchBlobFileResp.isDownloadComplete() == false){
549
-                    callback.invoke("RNFetchBlob failed. Download interrupted.", null);
596
+                if(rnFetchBlobFileResp != null && !rnFetchBlobFileResp.isDownloadComplete()){
597
+                    callback.invoke("Download interrupted.", null);
550 598
                 }
551 599
                 else {
552 600
                     this.destPath = this.destPath.replace("?append=true", "");
553 601
                     callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
554 602
                 }
603
+
555 604
                 break;
556 605
             default:
557 606
                 try {
@@ -685,7 +734,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
685 734
                 }
686 735
 
687 736
                 String filePath = null;
688
-                try {    
737
+                try {
689 738
                     // the file exists in media content database
690 739
                     if (c.moveToFirst()) {
691 740
                         // #297 handle failed request

+ 10
- 0
index.d.ts Zobrazit soubor

@@ -546,6 +546,16 @@ export interface RNFetchBlobConfig {
546 546
      */
547 547
     trusty?: boolean;
548 548
 
549
+    /**
550
+     * Set this property to true will only do requests through the WiFi interface, and fail otherwise.
551
+     */
552
+    wifiOnly?: boolean;
553
+
554
+    /**
555
+     * Set this property so redirects are not automatically followed.
556
+     */
557
+    followRedirect?: boolean;
558
+
549 559
     /**
550 560
      * Set this property to true will makes response data of the fetch stored in a temp file, by default the temp
551 561
      * file will stored in App's own root folder with file name template RNFetchBlob_tmp${timestamp}.

+ 6
- 0
index.js Zobrazit soubor

@@ -105,6 +105,12 @@ function wrap(path:string):string {
105 105
  *                   If it doesn't exist, the file is downloaded as usual
106 106
  *         @property {number} timeout
107 107
  *                   Request timeout in millionseconds, by default it's 60000ms.
108
+ *         @property {boolean} followRedirect
109
+ *                   Follow redirects automatically, default true
110
+ *         @property {boolean} trusty
111
+ *                   Trust all certificates
112
+ *         @property {boolean} wifiOnly
113
+ *                   Only do requests through WiFi. Android SDK 21 or above only.
108 114
  *
109 115
  * @return {function} This method returns a `fetch` method instance.
110 116
  */

+ 3
- 1
index.js.flow Zobrazit soubor

@@ -163,7 +163,9 @@ export type RNFetchBlobConfig = {
163 163
   path?: string,
164 164
   session?: string,
165 165
   timeout?: number,
166
-  trusty?: boolean
166
+  trusty?: boolean,
167
+  wifiOnly?: boolean,
168
+  followRedirect?: boolean
167 169
 };
168 170
 export type RNFetchBlobResponseInfo = {
169 171
   headers: {[fieldName: string]: string},

+ 1
- 0
ios/RNFetchBlobConst.h Zobrazit soubor

@@ -32,6 +32,7 @@ extern NSString *const CONFIG_USE_TEMP;
32 32
 extern NSString *const CONFIG_FILE_PATH;
33 33
 extern NSString *const CONFIG_FILE_EXT;
34 34
 extern NSString *const CONFIG_TRUSTY;
35
+extern NSString *const CONFIG_WIFI_ONLY;
35 36
 extern NSString *const CONFIG_INDICATOR;
36 37
 extern NSString *const CONFIG_KEY;
37 38
 extern NSString *const CONFIG_EXTRA_BLOB_CTYPE;

+ 1
- 0
ios/RNFetchBlobConst.m Zobrazit soubor

@@ -16,6 +16,7 @@ NSString *const CONFIG_USE_TEMP = @"fileCache";
16 16
 NSString *const CONFIG_FILE_PATH = @"path";
17 17
 NSString *const CONFIG_FILE_EXT = @"appendExt";
18 18
 NSString *const CONFIG_TRUSTY = @"trusty";
19
+NSString *const CONFIG_WIFI_ONLY = @"wifiOnly";
19 20
 NSString *const CONFIG_INDICATOR = @"indicator";
20 21
 NSString *const CONFIG_KEY = @"key";
21 22
 NSString *const CONFIG_EXTRA_BLOB_CTYPE = @"binaryContentTypes";

+ 68
- 61
ios/RNFetchBlobRequest.m Zobrazit soubor

@@ -56,7 +56,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
56 56
     const char* str = [input UTF8String];
57 57
     unsigned char result[CC_MD5_DIGEST_LENGTH];
58 58
     CC_MD5(str, (CC_LONG)strlen(str), result);
59
-    
59
+
60 60
     NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
61 61
     for (int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
62 62
         [ret appendFormat:@"%02x",result[i]];
@@ -80,20 +80,20 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
80 80
     self.expectedBytes = 0;
81 81
     self.receivedBytes = 0;
82 82
     self.options = options;
83
-    
83
+
84 84
     backgroundTask = [[options valueForKey:@"IOSBackgroundTask"] boolValue];
85 85
     // when followRedirect not set in options, defaults to TRUE
86 86
     followRedirect = [options valueForKey:@"followRedirect"] == nil ? YES : [[options valueForKey:@"followRedirect"] boolValue];
87 87
     isIncrement = [[options valueForKey:@"increment"] boolValue];
88 88
     redirects = [[NSMutableArray alloc] init];
89
-    
89
+
90 90
     if (req.URL) {
91 91
         [redirects addObject:req.URL.absoluteString];
92 92
     }
93
-    
93
+
94 94
     // set response format
95 95
     NSString * rnfbResp = [req.allHTTPHeaderFields valueForKey:@"RNFB-Response"];
96
-    
96
+
97 97
     if ([[rnfbResp lowercaseString] isEqualToString:@"base64"]) {
98 98
         responseFormat = BASE64;
99 99
     } else if ([[rnfbResp lowercaseString] isEqualToString:@"utf8"]) {
@@ -101,52 +101,56 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
101 101
     } else {
102 102
         responseFormat = AUTO;
103 103
     }
104
-    
104
+
105 105
     NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
106 106
     NSString * key = [self.options valueForKey:CONFIG_KEY];
107 107
     NSURLSession * session;
108
-    
108
+
109 109
     bodyLength = contentLength;
110
-    
110
+
111 111
     // the session trust any SSL certification
112 112
     NSURLSessionConfiguration *defaultConfigObject;
113
-    
113
+
114 114
     defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
115
-    
115
+
116 116
     if (backgroundTask) {
117 117
         defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:taskId];
118 118
     }
119
-    
119
+
120 120
     // request timeout, -1 if not set in options
121 121
     float timeout = [options valueForKey:@"timeout"] == nil ? -1 : [[options valueForKey:@"timeout"] floatValue];
122
-    
122
+
123 123
     if (timeout > 0) {
124 124
         defaultConfigObject.timeoutIntervalForRequest = timeout/1000;
125 125
     }
126
-    
126
+
127
+    if([options valueForKey:CONFIG_WIFI_ONLY] != nil && ![options[CONFIG_WIFI_ONLY] boolValue]){
128
+        [defaultConfigObject setAllowsCellularAccess:NO];
129
+    }
130
+
127 131
     defaultConfigObject.HTTPMaximumConnectionsPerHost = 10;
128 132
     session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:operationQueue];
129
-    
133
+
130 134
     if (path || [self.options valueForKey:CONFIG_USE_TEMP]) {
131 135
         respFile = YES;
132
-        
136
+
133 137
         NSString* cacheKey = taskId;
134 138
         if (key) {
135 139
             cacheKey = [self md5:key];
136
-            
140
+
137 141
             if (!cacheKey) {
138 142
                 cacheKey = taskId;
139 143
             }
140
-            
144
+
141 145
             destPath = [RNFetchBlobFS getTempPath:cacheKey withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
142
-            
146
+
143 147
             if ([[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
144 148
                 callback(@[[NSNull null], RESP_TYPE_PATH, destPath]);
145
-                
149
+
146 150
                 return;
147 151
             }
148 152
         }
149
-        
153
+
150 154
         if (path) {
151 155
             destPath = path;
152 156
         } else {
@@ -156,10 +160,10 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
156 160
         respData = [[NSMutableData alloc] init];
157 161
         respFile = NO;
158 162
     }
159
-    
163
+
160 164
     self.task = [session dataTaskWithRequest:req];
161 165
     [self.task resume];
162
-    
166
+
163 167
     // network status indicator
164 168
     if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) {
165 169
         dispatch_async(dispatch_get_main_queue(), ^{
@@ -183,17 +187,17 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
183 187
 - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
184 188
 {
185 189
     expectedBytes = [response expectedContentLength];
186
-    
190
+
187 191
     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
188 192
     NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
189 193
     NSString * respType = @"";
190 194
     respStatus = statusCode;
191
-    
195
+
192 196
     if ([response respondsToSelector:@selector(allHeaderFields)])
193 197
     {
194 198
         NSDictionary *headers = [httpResponse allHeaderFields];
195 199
         NSString * respCType = [[RNFetchBlobReqBuilder getHeaderIgnoreCases:@"Content-Type" fromHeaders:headers] lowercaseString];
196
-        
200
+
197 201
         if (self.isServerPush) {
198 202
             if (partBuffer) {
199 203
                 [self.bridge.eventDispatcher
@@ -204,7 +208,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
204 208
                         }
205 209
                  ];
206 210
             }
207
-            
211
+
208 212
             partBuffer = [[NSMutableData alloc] init];
209 213
             completionHandler(NSURLSessionResponseAllow);
210 214
 
@@ -212,11 +216,11 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
212 216
         } else {
213 217
             self.isServerPush = [[respCType lowercaseString] RNFBContainsString:@"multipart/x-mixed-replace;"];
214 218
         }
215
-        
219
+
216 220
         if(respCType)
217 221
         {
218 222
             NSArray * extraBlobCTypes = [options objectForKey:CONFIG_EXTRA_BLOB_CTYPE];
219
-            
223
+
220 224
             if ([respCType RNFBContainsString:@"text/"]) {
221 225
                 respType = @"text";
222 226
             } else if ([respCType RNFBContainsString:@"application/json"]) {
@@ -232,7 +236,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
232 236
                 }
233 237
             } else {
234 238
                 respType = @"blob";
235
-                
239
+
236 240
                 // for XMLHttpRequest, switch response data handling strategy automatically
237 241
                 if ([options valueForKey:@"auto"]) {
238 242
                     respFile = YES;
@@ -242,7 +246,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
242 246
         } else {
243 247
             respType = @"text";
244 248
         }
245
-        
249
+
246 250
 #pragma mark - handling cookies
247 251
         // # 153 get cookies
248 252
         if (response.URL) {
@@ -252,7 +256,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
252 256
                 [cookieStore setCookies:cookies forURL:response.URL mainDocumentURL:nil];
253 257
             }
254 258
         }
255
-        
259
+
256 260
         [self.bridge.eventDispatcher
257 261
          sendDeviceEventWithName: EVENT_STATE_CHANGE
258 262
          body:@{
@@ -268,33 +272,33 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
268 272
     } else {
269 273
         NSLog(@"oops");
270 274
     }
271
-    
275
+
272 276
     if (respFile)
273 277
     {
274 278
         @try{
275 279
             NSFileManager * fm = [NSFileManager defaultManager];
276 280
             NSString * folder = [destPath stringByDeletingLastPathComponent];
277
-            
281
+
278 282
             if (![fm fileExistsAtPath:folder]) {
279 283
                 [fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil];
280 284
             }
281
-            
285
+
282 286
             // if not set overwrite in options, defaults to TRUE
283 287
             BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue];
284 288
             BOOL appendToExistingFile = [destPath RNFBContainsString:@"?append=true"];
285
-            
289
+
286 290
             appendToExistingFile = !overwrite;
287
-            
291
+
288 292
             // For solving #141 append response data if the file already exists
289 293
             // base on PR#139 @kejinliang
290 294
             if (appendToExistingFile) {
291 295
                 destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""];
292 296
             }
293
-            
297
+
294 298
             if (![fm fileExistsAtPath:destPath]) {
295 299
                 [fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil];
296 300
             }
297
-            
301
+
298 302
             writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile];
299 303
             [writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
300 304
             [writeStream open];
@@ -304,7 +308,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
304 308
             NSLog(@"write file error");
305 309
         }
306 310
     }
307
-    
311
+
308 312
     completionHandler(NSURLSessionResponseAllow);
309 313
 }
310 314
 
@@ -316,30 +320,30 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
316 320
     if (self.isServerPush)
317 321
     {
318 322
         [partBuffer appendData:data];
319
-        
323
+
320 324
         return ;
321 325
     }
322
-    
326
+
323 327
     NSNumber * received = [NSNumber numberWithLong:[data length]];
324 328
     receivedBytes += [received longValue];
325 329
     NSString * chunkString = @"";
326
-    
330
+
327 331
     if (isIncrement) {
328 332
         chunkString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
329 333
     }
330
-    
334
+
331 335
     if (respFile) {
332 336
         [writeStream write:[data bytes] maxLength:[data length]];
333 337
     } else {
334 338
         [respData appendData:data];
335 339
     }
336
-    
340
+
337 341
     if (expectedBytes == 0) {
338 342
         return;
339 343
     }
340
-    
344
+
341 345
     NSNumber * now =[NSNumber numberWithFloat:((float)receivedBytes/(float)expectedBytes)];
342
-    
346
+
343 347
     if ([self.progressConfig shouldReport:now]) {
344 348
         [self.bridge.eventDispatcher
345 349
          sendDeviceEventWithName:EVENT_PROGRESS
@@ -363,16 +367,19 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
363 367
 
364 368
 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
365 369
 {
366
-    
370
+
367 371
     self.error = error;
368 372
     NSString * errMsg;
369 373
     NSString * respStr;
370 374
     NSString * rnfbRespType;
371
-    
372
-    dispatch_async(dispatch_get_main_queue(), ^{
373
-        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
374
-    });
375
-    
375
+
376
+    // only run this if we were requested to change it
377
+    if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) {
378
+        dispatch_async(dispatch_get_main_queue(), ^{
379
+            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
380
+        });
381
+    }
382
+
376 383
     if (error) {
377 384
         if (error.domain == NSURLErrorDomain && error.code == NSURLErrorCancelled) {
378 385
             errMsg = @"task cancelled";
@@ -380,7 +387,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
380 387
             errMsg = [error localizedDescription];
381 388
         }
382 389
     }
383
-    
390
+
384 391
     if (respFile) {
385 392
         [writeStream close];
386 393
         rnfbRespType = RESP_TYPE_PATH;
@@ -391,7 +398,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
391 398
         // if it turns out not to be `nil` that means the response data contains valid UTF8 string,
392 399
         // in order to properly encode the UTF8 string, use URL encoding before BASE64 encoding.
393 400
         NSString * utf8 = [[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding];
394
-        
401
+
395 402
         if (responseFormat == BASE64) {
396 403
             rnfbRespType = RESP_TYPE_BASE64;
397 404
             respStr = [respData base64EncodedStringWithOptions:0];
@@ -408,18 +415,18 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
408 415
             }
409 416
         }
410 417
     }
411
-    
412
-    
418
+
419
+
413 420
     callback(@[
414 421
                errMsg ?: [NSNull null],
415 422
                rnfbRespType ?: @"",
416 423
                respStr ?: [NSNull null]
417 424
                ]);
418
-    
425
+
419 426
     respData = nil;
420 427
     receivedBytes = 0;
421 428
     [session finishTasksAndInvalidate];
422
-    
429
+
423 430
 }
424 431
 
425 432
 // upload progress handler
@@ -428,7 +435,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
428 435
     if (totalBytesExpectedToWrite == 0) {
429 436
         return;
430 437
     }
431
-    
438
+
432 439
     NSNumber * now = [NSNumber numberWithFloat:((float)totalBytesWritten/(float)totalBytesExpectedToWrite)];
433 440
 
434 441
     if ([self.uploadProgressConfig shouldReport:now]) {
@@ -461,12 +468,12 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
461 468
 
462 469
 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler
463 470
 {
464
-    
471
+
465 472
     if (followRedirect) {
466 473
         if (request.URL) {
467 474
             [redirects addObject:[request.URL absoluteString]];
468 475
         }
469
-        
476
+
470 477
         completionHandler(request);
471 478
     } else {
472 479
         completionHandler(nil);

+ 4
- 1
types.js Zobrazit soubor

@@ -5,7 +5,10 @@ type RNFetchBlobConfig = {
5 5
   appendExt : string,
6 6
   session : string,
7 7
   addAndroidDownloads : any,
8
-  indicator : bool
8
+  indicator : bool,
9
+  followRedirect : bool,
10
+  trusty : bool,
11
+  wifiOnly : bool
9 12
 };
10 13
 
11 14
 type RNFetchBlobNative = {