Quellcode durchsuchen

Merge branch '0.10.5' into issue-287-wip

Ben Hsieh vor 8 Jahren
Ursprung
Commit
4d15c0f3ed

+ 6
- 1
README.md Datei anzeigen

3
 
3
 
4
 
4
 
5
 A project committed to making file access and data transfer easier, efficient for React Native developers.
5
 A project committed to making file access and data transfer easier, efficient for React Native developers.
6
-
7
 > For Firebase Storage solution, please upgrade to latest version for best compatibility.
6
 > For Firebase Storage solution, please upgrade to latest version for best compatibility.
8
 
7
 
9
 ## Features
8
 ## Features
61
     :path => '../node_modules/react-native-fetch-blob'
60
     :path => '../node_modules/react-native-fetch-blob'
62
 ```
61
 ```
63
 
62
 
63
+After `0.10.3` you can install this package directly from Github 
64
+
65
+```sh
66
+# replace <branch_name> with any one of the branches
67
+npm install --save github:wkh237/react-native-fetch-blob-package#<branch_name>
68
+```
64
 **Automatically Link Native Modules**
69
 **Automatically Link Native Modules**
65
 
70
 
66
 For 0.29.2+ projects, simply link native packages via the following command because rnpm has been merged into react-native, you no longer need it.
71
 For 0.29.2+ projects, simply link native packages via the following command because rnpm has been merged into react-native, you no longer need it.

+ 9
- 1
android.js Datei anzeigen

24
     return Promise.reject('RNFetchBlob.actionViewIntent only supports Android.')
24
     return Promise.reject('RNFetchBlob.actionViewIntent only supports Android.')
25
 }
25
 }
26
 
26
 
27
+function getContentIntent(mime:string) {
28
+  if(Platform.OS === 'android')
29
+    return RNFetchBlob.getContentIntent(mime)
30
+  else
31
+    return Promise.reject('RNFetchBlob.getContentIntent only supports Android.')
32
+}
33
+
27
 
34
 
28
 export default {
35
 export default {
29
-  actionViewIntent
36
+  actionViewIntent,
37
+  getContentIntent
30
 }
38
 }

+ 36
- 0
android/src/main/java/com/RNFetchBlob/RNFetchBlob.java Datei anzeigen

1
 package com.RNFetchBlob;
1
 package com.RNFetchBlob;
2
 
2
 
3
+import android.app.Activity;
3
 import android.content.Intent;
4
 import android.content.Intent;
4
 import android.net.Uri;
5
 import android.net.Uri;
6
+import android.util.Log;
5
 
7
 
6
 import com.RNFetchBlob.Utils.RNFBCookieJar;
8
 import com.RNFetchBlob.Utils.RNFBCookieJar;
9
+import com.facebook.react.bridge.ActivityEventListener;
7
 import com.facebook.react.bridge.Callback;
10
 import com.facebook.react.bridge.Callback;
8
 import com.facebook.react.bridge.LifecycleEventListener;
11
 import com.facebook.react.bridge.LifecycleEventListener;
9
 import com.facebook.react.bridge.Promise;
12
 import com.facebook.react.bridge.Promise;
15
 import com.facebook.react.bridge.WritableArray;
18
 import com.facebook.react.bridge.WritableArray;
16
 import com.facebook.react.bridge.WritableMap;
19
 import com.facebook.react.bridge.WritableMap;
17
 
20
 
21
+import java.util.HashMap;
18
 import java.util.Map;
22
 import java.util.Map;
23
+import java.util.UUID;
19
 import java.util.concurrent.LinkedBlockingQueue;
24
 import java.util.concurrent.LinkedBlockingQueue;
20
 import java.util.concurrent.ThreadPoolExecutor;
25
 import java.util.concurrent.ThreadPoolExecutor;
21
 import java.util.concurrent.TimeUnit;
26
 import java.util.concurrent.TimeUnit;
22
 
27
 
28
+import static android.app.Activity.RESULT_OK;
29
+import static com.RNFetchBlob.RNFetchBlobConst.GET_CONTENT_INTENT;
30
+
23
 public class RNFetchBlob extends ReactContextBaseJavaModule {
31
 public class RNFetchBlob extends ReactContextBaseJavaModule {
24
 
32
 
25
     static ReactApplicationContext RCTContext;
33
     static ReactApplicationContext RCTContext;
28
     static LinkedBlockingQueue<Runnable> fsTaskQueue = new LinkedBlockingQueue<>();
36
     static LinkedBlockingQueue<Runnable> fsTaskQueue = new LinkedBlockingQueue<>();
29
     static ThreadPoolExecutor fsThreadPool = new ThreadPoolExecutor(2, 10, 5000, TimeUnit.MILLISECONDS, taskQueue);
37
     static ThreadPoolExecutor fsThreadPool = new ThreadPoolExecutor(2, 10, 5000, TimeUnit.MILLISECONDS, taskQueue);
30
     static public boolean ActionViewVisible = false;
38
     static public boolean ActionViewVisible = false;
39
+    static HashMap<Integer, Promise> promiseTable = new HashMap<>();
31
 
40
 
32
     public RNFetchBlob(ReactApplicationContext reactContext) {
41
     public RNFetchBlob(ReactApplicationContext reactContext) {
33
 
42
 
34
         super(reactContext);
43
         super(reactContext);
35
 
44
 
36
         RCTContext = reactContext;
45
         RCTContext = reactContext;
46
+        reactContext.addActivityEventListener(new ActivityEventListener() {
47
+            @Override
48
+            public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
49
+                if(requestCode == GET_CONTENT_INTENT && resultCode == RESULT_OK) {
50
+                    Uri d = data.getData();
51
+                    promiseTable.get(GET_CONTENT_INTENT).resolve(d.toString());
52
+                    promiseTable.remove(GET_CONTENT_INTENT);
53
+                }
54
+            }
55
+
56
+            @Override
57
+            public void onNewIntent(Intent intent) {
58
+
59
+            }
60
+        });
37
     }
61
     }
38
 
62
 
39
     @Override
63
     @Override
322
         new RNFetchBlobReq(options, taskId, method, url, headers, null, body, callback).run();
346
         new RNFetchBlobReq(options, taskId, method, url, headers, null, body, callback).run();
323
     }
347
     }
324
 
348
 
349
+    @ReactMethod
350
+    public void getContentIntent(String mime, Promise promise) {
351
+        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
352
+        if(mime != null)
353
+            i.setType(mime);
354
+        else
355
+            i.setType("*/*");
356
+        promiseTable.put(GET_CONTENT_INTENT, promise);
357
+        this.getReactApplicationContext().startActivityForResult(i, GET_CONTENT_INTENT, null);
358
+
359
+    }
360
+
325
 }
361
 }

+ 1
- 0
android/src/main/java/com/RNFetchBlob/RNFetchBlobConst.java Datei anzeigen

13
     public static final String RNFB_RESPONSE_BASE64 = "base64";
13
     public static final String RNFB_RESPONSE_BASE64 = "base64";
14
     public static final String RNFB_RESPONSE_UTF8  = "utf8";
14
     public static final String RNFB_RESPONSE_UTF8  = "utf8";
15
     public static final String RNFB_RESPONSE_PATH  = "path";
15
     public static final String RNFB_RESPONSE_PATH  = "path";
16
+    public static final Integer GET_CONTENT_INTENT = 99900;
16
 
17
 
17
 }
18
 }

+ 4
- 2
android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java Datei anzeigen

265
                 while ((cursor = fs.read(buffer)) != -1) {
265
                 while ((cursor = fs.read(buffer)) != -1) {
266
                     encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
266
                     encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
267
                     String chunk = new String(buffer);
267
                     String chunk = new String(buffer);
268
-                    if(cursor != bufferSize)
268
+                    if(cursor != bufferSize) {
269
                         chunk = chunk.substring(0, cursor);
269
                         chunk = chunk.substring(0, cursor);
270
+                    }
270
                     emitStreamEvent(streamId, "data", chunk);
271
                     emitStreamEvent(streamId, "data", chunk);
271
                     if(tick > 0)
272
                     if(tick > 0)
272
                         SystemClock.sleep(tick);
273
                         SystemClock.sleep(tick);
308
             buffer = null;
309
             buffer = null;
309
 
310
 
310
         } catch (Exception err) {
311
         } catch (Exception err) {
311
-            emitStreamEvent(streamId, "error", "Failed to convert data to "+encoding+" encoded string, this might due to the source data is not able to convert using this encoding.");
312
+            emitStreamEvent(streamId, "warn", "Failed to convert data to "+encoding+" encoded string, this might due to the source data is not able to convert using this encoding.");
313
+            err.printStackTrace();
312
         }
314
         }
313
     }
315
     }
314
 
316
 

+ 10
- 30
android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java Datei anzeigen

220
                             responseFormat = ResponseFormat.UTF8;
220
                             responseFormat = ResponseFormat.UTF8;
221
                     }
221
                     }
222
                     else {
222
                     else {
223
-                        builder.header(key, value);
224
-                        mheaders.put(key, value);
223
+                        builder.header(key.toLowerCase(), value);
224
+                        mheaders.put(key.toLowerCase(), value);
225
                     }
225
                     }
226
                 }
226
                 }
227
             }
227
             }
304
             clientBuilder.addNetworkInterceptor(new Interceptor() {
304
             clientBuilder.addNetworkInterceptor(new Interceptor() {
305
                 @Override
305
                 @Override
306
                 public Response intercept(Chain chain) throws IOException {
306
                 public Response intercept(Chain chain) throws IOException {
307
-                        redirects.add(chain.request().url().toString());
308
-                        return chain.proceed(chain.request());
309
-                    }
307
+                    redirects.add(chain.request().url().toString());
308
+                    return chain.proceed(chain.request());
309
+                }
310
             });
310
             });
311
             // Add request interceptor for upload progress event
311
             // Add request interceptor for upload progress event
312
             clientBuilder.addInterceptor(new Interceptor() {
312
             clientBuilder.addInterceptor(new Interceptor() {
500
                     // It uses customized response body which is able to report download progress
500
                     // It uses customized response body which is able to report download progress
501
                     // and write response data to destination path.
501
                     // and write response data to destination path.
502
                     resp.body().bytes();
502
                     resp.body().bytes();
503
-
504
                 } catch (Exception ignored) {
503
                 } catch (Exception ignored) {
505
 //                    ignored.printStackTrace();
504
 //                    ignored.printStackTrace();
506
                 }
505
                 }
507
                 this.destPath = this.destPath.replace("?append=true", "");
506
                 this.destPath = this.destPath.replace("?append=true", "");
508
-
509
-                try {
510
-                    long expectedLength = resp.body().contentLength();
511
-                    // when response contains Content-Length, check if the stream length is correct
512
-                    if(expectedLength > 0) {
513
-                        long actualLength = new File(this.destPath).length();
514
-                        if(actualLength != expectedLength) {
515
-                            callback.invoke("RNFetchBlob failed to write data to storage : expected " + expectedLength + " bytes but got " + actualLength + " bytes", null);
516
-                        }
517
-                        else {
518
-                            callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
519
-                        }
520
-                    }
521
-                    else {
522
-                        callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
523
-                    }
524
-                }
525
-                catch (Exception err) {
526
-                    callback.invoke(err.getMessage());
527
-                    err.printStackTrace();
528
-                }
507
+                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
529
                 break;
508
                 break;
530
             default:
509
             default:
531
                 try {
510
                 try {
536
                 break;
515
                 break;
537
         }
516
         }
538
 //        if(!resp.isSuccessful())
517
 //        if(!resp.isSuccessful())
539
-            resp.body().close();
518
+        resp.body().close();
540
         releaseTaskResource();
519
         releaseTaskResource();
541
     }
520
     }
542
 
521
 
578
         }
557
         }
579
         WritableArray redirectList = Arguments.createArray();
558
         WritableArray redirectList = Arguments.createArray();
580
         for(String r : redirects) {
559
         for(String r : redirects) {
581
-                redirectList.pushString(r);
560
+            redirectList.pushString(r);
582
         }
561
         }
583
         info.putArray("redirects", redirectList);
562
         info.putArray("redirects", redirectList);
584
         info.putMap("headers", headers);
563
         info.putMap("headers", headers);
629
     private String getHeaderIgnoreCases(HashMap<String,String> headers, String field) {
608
     private String getHeaderIgnoreCases(HashMap<String,String> headers, String field) {
630
         String val = headers.get(field);
609
         String val = headers.get(field);
631
         if(val != null) return val;
610
         if(val != null) return val;
632
-        return headers.get(field.toLowerCase()) == null ? "" : headers.get(field.toLowerCase());
611
+        String lowerCasedValue = headers.get(field.toLowerCase());
612
+        return lowerCasedValue == null ? "" : lowerCasedValue;
633
     }
613
     }
634
 
614
 
635
     private void emitStateEvent(WritableMap args) {
615
     private void emitStateEvent(WritableMap args) {

+ 4
- 3
index.js Datei anzeigen

220
 
220
 
221
   // # 241 normalize null or undefined headers, in case nil or null string
221
   // # 241 normalize null or undefined headers, in case nil or null string
222
   // pass to native context
222
   // pass to native context
223
-  _.each(headers, (h,i) =>  {
224
-    headers[i] = h || ''
225
-  });
223
+  headers = _.reduce(headers, (result, value, key) => {
224
+    result[key] = value || ''
225
+    return result
226
+  }, {});
226
 
227
 
227
   // fetch from file system
228
   // fetch from file system
228
   if(URIUtil.isFileURI(url)) {
229
   if(URIUtil.isFileURI(url)) {

+ 55
- 8
ios/RNFetchBlob/RNFetchBlob.m Datei anzeigen

80
                   callback:(RCTResponseSenderBlock)callback)
80
                   callback:(RCTResponseSenderBlock)callback)
81
 {
81
 {
82
 
82
 
83
-    [RNFetchBlobReqBuilder buildMultipartRequest:options taskId:taskId method:method url:url headers:headers form:form onComplete:^(__weak NSURLRequest *req, long bodyLength) {
83
+    [RNFetchBlobReqBuilder buildMultipartRequest:options
84
+                                          taskId:taskId
85
+                                          method:method
86
+                                             url:url
87
+                                         headers:headers
88
+                                            form:form
89
+                                      onComplete:^(__weak NSURLRequest *req, long bodyLength)
90
+    {
91
+        // something went wrong when building the request body
92
+        if(req == nil)
93
+        {
94
+            callback(@[@"RNFetchBlob.fetchBlobForm failed to create request body"]);
95
+        }
84
         // send HTTP request
96
         // send HTTP request
85
-        RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
86
-        [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
97
+        else
98
+        {
99
+            RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
100
+            [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
101
+        }
87
     }];
102
     }];
88
 
103
 
89
 }
104
 }
97
                   headers:(NSDictionary *)headers
112
                   headers:(NSDictionary *)headers
98
                   body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
113
                   body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
99
 {
114
 {
100
-    [RNFetchBlobReqBuilder buildOctetRequest:options taskId:taskId method:method url:url headers:headers body:body onComplete:^(NSURLRequest *req, long bodyLength) {
115
+    [RNFetchBlobReqBuilder buildOctetRequest:options
116
+                                      taskId:taskId
117
+                                      method:method
118
+                                         url:url
119
+                                     headers:headers
120
+                                        body:body
121
+                                  onComplete:^(NSURLRequest *req, long bodyLength)
122
+    {
123
+        // something went wrong when building the request body
124
+        if(req == nil)
125
+        {
126
+            callback(@[@"RNFetchBlob.fetchBlob failed to create request body"]);
127
+        }
101
         // send HTTP request
128
         // send HTTP request
102
-        __block RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
103
-        [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
129
+        else
130
+        {
131
+            __block RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
132
+            [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
133
+        }
104
     }];
134
     }];
105
 }
135
 }
106
 
136
 
394
 }
424
 }
395
 
425
 
396
 #pragma mark - fs.readFile
426
 #pragma mark - fs.readFile
397
-RCT_EXPORT_METHOD(readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
427
+RCT_EXPORT_METHOD(readFile:(NSString *)path
428
+                  encoding:(NSString *)encoding
429
+                  resolver:(RCTPromiseResolveBlock)resolve
430
+                  rejecter:(RCTPromiseRejectBlock)reject)
398
 {
431
 {
399
 
432
 
400
-    [RNFetchBlobFS readFile:path encoding:encoding resolver:resolve rejecter:reject onComplete:nil];
433
+    [RNFetchBlobFS readFile:path encoding:encoding onComplete:^(id content, NSString * err) {
434
+        if(err != nil)
435
+        {
436
+            reject(@"RNFetchBlob failed to read file", err, nil);
437
+            return;
438
+        }
439
+        if(encoding == @"ascii")
440
+        {
441
+            resolve((NSMutableArray *)content);
442
+        }
443
+        else
444
+        {
445
+            resolve((NSString *)content);
446
+        }
447
+    }];
401
 }
448
 }
402
 
449
 
403
 #pragma mark - fs.readStream
450
 #pragma mark - fs.readStream

+ 1
- 1
ios/RNFetchBlobFS.h Datei anzeigen

61
 + (void) exists:(NSString *) path callback:(RCTResponseSenderBlock)callback;
61
 + (void) exists:(NSString *) path callback:(RCTResponseSenderBlock)callback;
62
 + (void) writeFileArray:(NSString *)path data:(NSArray *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
62
 + (void) writeFileArray:(NSString *)path data:(NSArray *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
63
 + (void) writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
63
 + (void) writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
64
-+ (void) readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject onComplete:(void (^)(NSData * content))onComplete;
64
++ (void) readFile:(NSString *)path encoding:(NSString *)encoding onComplete:(void (^)(NSData * content, NSString * errMsg))onComplete;
65
 + (void) readAssetFile:(NSData *)assetUrl completionBlock:(void(^)(NSData * content))completionBlock failBlock:(void(^)(NSError * err))failBlock;
65
 + (void) readAssetFile:(NSData *)assetUrl completionBlock:(void(^)(NSData * content))completionBlock failBlock:(void(^)(NSError * err))failBlock;
66
 + (void) slice:(NSString *)path
66
 + (void) slice:(NSString *)path
67
          dest:(NSString *)dest
67
          dest:(NSString *)dest

+ 49
- 57
ios/RNFetchBlobFS.m Datei anzeigen

418
 
418
 
419
 # pragma mark - read file
419
 # pragma mark - read file
420
 
420
 
421
-+ (void) readFile:(NSString *)path encoding:(NSString *)encoding
422
-         resolver:(RCTPromiseResolveBlock)resolve
423
-         rejecter:(RCTPromiseRejectBlock)reject
424
-       onComplete:(void (^)(NSData * content))onComplete
421
++ (void) readFile:(NSString *)path
422
+         encoding:(NSString *)encoding
423
+       onComplete:(void (^)(id content, NSString * errMsg))onComplete
425
 {
424
 {
426
-    @try
427
-    {
428
-        [[self class] getPathFromUri:path completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
429
-            __block NSData * fileContent;
430
-            NSError * err;
431
-            __block Byte * buffer;
432
-            if(asset != nil)
425
+    [[self class] getPathFromUri:path completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
426
+        __block NSData * fileContent;
427
+        NSError * err;
428
+        __block Byte * buffer;
429
+        if(asset != nil)
430
+        {
431
+            buffer = malloc(asset.size);
432
+            [asset getBytes:buffer fromOffset:0 length:asset.size error:&err];
433
+            if(err != nil)
433
             {
434
             {
434
-                buffer = malloc(asset.size);
435
-                [asset getBytes:buffer fromOffset:0 length:asset.size error:&err];
436
-                if(err != nil)
437
-                {
438
-                    reject(@"RNFetchBlobFS readFile error", @"failed to read asset", [err localizedDescription]);
439
-                    return;
440
-                }
441
-                fileContent = [NSData dataWithBytes:buffer length:asset.size];
435
+                onComplete(nil, [err description]);
442
                 free(buffer);
436
                 free(buffer);
437
+                return;
443
             }
438
             }
444
-            else
445
-            {
446
-                if(![[NSFileManager defaultManager] fileExistsAtPath:path]) {
447
-
448
-                    reject(@"RNFetchBlobFS readFile error", @"file not exists", nil);
449
-                    return;
450
-                }
451
-                fileContent = [NSData dataWithContentsOfFile:path];
452
-
439
+            fileContent = [NSData dataWithBytes:buffer length:asset.size];
440
+            free(buffer);
441
+        }
442
+        else
443
+        {
444
+            if(![[NSFileManager defaultManager] fileExistsAtPath:path]) {
445
+                onComplete(nil, @"file not exists");
446
+                return;
453
             }
447
             }
454
-            if(onComplete != nil)
455
-                onComplete(fileContent);
456
-
457
-            if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
458
-                if(resolve != nil) {
459
-                    NSString * utf8 = [[NSString alloc] initWithData:fileContent encoding:NSUTF8StringEncoding];
460
-                    if(utf8 == nil)
461
-                        resolve([[NSString alloc] initWithData:fileContent encoding:NSISOLatin1StringEncoding]);
462
-                    else
463
-                        resolve(utf8);
464
-                }
448
+            fileContent = [NSData dataWithContentsOfFile:path];
449
+            
450
+        }
451
+        
452
+        if(encoding != nil)
453
+        {
454
+            if([[encoding lowercaseString] isEqualToString:@"utf8"])
455
+            {
456
+                NSString * utf8 = [[NSString alloc] initWithData:fileContent encoding:NSUTF8StringEncoding];
457
+                if(utf8 == nil)
458
+                    onComplete([[NSString alloc] initWithData:fileContent encoding:NSISOLatin1StringEncoding], nil);
459
+                else
460
+                    onComplete(utf8, nil);
465
             }
461
             }
466
             else if ([[encoding lowercaseString] isEqualToString:@"base64"]) {
462
             else if ([[encoding lowercaseString] isEqualToString:@"base64"]) {
467
-                if(resolve != nil)
468
-                    resolve([fileContent base64EncodedStringWithOptions:0]);
463
+                onComplete([fileContent base64EncodedStringWithOptions:0], nil);
469
             }
464
             }
470
             else if ([[encoding lowercaseString] isEqualToString:@"ascii"]) {
465
             else if ([[encoding lowercaseString] isEqualToString:@"ascii"]) {
471
                 NSMutableArray * resultArray = [NSMutableArray array];
466
                 NSMutableArray * resultArray = [NSMutableArray array];
473
                 for(int i=0;i<[fileContent length];i++) {
468
                 for(int i=0;i<[fileContent length];i++) {
474
                     [resultArray addObject:[NSNumber numberWithChar:bytes[i]]];
469
                     [resultArray addObject:[NSNumber numberWithChar:bytes[i]]];
475
                 }
470
                 }
476
-                if(resolve != nil)
477
-                    resolve(resultArray);
471
+                onComplete(resultArray, nil);
478
             }
472
             }
479
-        }];
480
-    }
481
-    @catch(NSException * e)
482
-    {
483
-        if(reject != nil)
484
-            reject(@"RNFetchBlobFS readFile error", @"error", [e description]);
485
-    }
473
+        }
474
+        else
475
+        {
476
+            onComplete(fileContent, nil);
477
+        }
478
+        
479
+    }];
486
 }
480
 }
487
 
481
 
482
+
488
 # pragma mark - mkdir
483
 # pragma mark - mkdir
489
 
484
 
490
 + (BOOL) mkdir:(NSString *) path {
485
 + (BOOL) mkdir:(NSString *) path {
516
              @"size" : size,
511
              @"size" : size,
517
              @"filename" : filename,
512
              @"filename" : filename,
518
              @"path" : path,
513
              @"path" : path,
519
-             @"lastModified" : [NSString stringWithFormat:@"%@", [NSNumber numberWithLong:(time_t) [lastModified timeIntervalSince1970]*1000]],
514
+             @"lastModified" : [NSNumber numberWithLong:(time_t) [lastModified timeIntervalSince1970]*1000],
520
              @"type" : isDir ? @"directory" : @"file"
515
              @"type" : isDir ? @"directory" : @"file"
521
             };
516
             };
522
 
517
 
753
 
748
 
754
 +(void) df:(RCTResponseSenderBlock)callback
749
 +(void) df:(RCTResponseSenderBlock)callback
755
 {
750
 {
756
-    uint64_t totalSpace = 0;
757
-    uint64_t totalFreeSpace = 0;
758
     NSError *error = nil;
751
     NSError *error = nil;
759
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
752
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
760
     NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
753
     NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
762
     if (dictionary) {
755
     if (dictionary) {
763
         NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
756
         NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
764
         NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
757
         NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
765
-        totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
766
-        totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
758
+        
767
         callback(@[[NSNull null], @{
759
         callback(@[[NSNull null], @{
768
-                  @"free" : [NSString stringWithFormat:@"%d", totalFreeSpace],
769
-                  @"total" : [NSString stringWithFormat:@"%d", totalSpace]
760
+                  @"free" : freeFileSystemSizeInBytes,
761
+                  @"total" : fileSystemSizeInBytes,
770
                 }]);
762
                 }]);
771
     } else {
763
     } else {
772
         callback(@[@"failed to get storage usage."]);
764
         callback(@[@"failed to get storage usage."]);

+ 0
- 18
ios/RNFetchBlobNetwork.h Datei anzeigen

23
 
23
 
24
 typedef void(^CompletionHander)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error);
24
 typedef void(^CompletionHander)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error);
25
 typedef void(^DataTaskCompletionHander) (NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error);
25
 typedef void(^DataTaskCompletionHander) (NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error);
26
-typedef NS_ENUM(NSUInteger, ResponseFormat) {
27
-    UTF8,
28
-    BASE64,
29
-    AUTO
30
-};
31
 
26
 
32
 @interface RNFetchBlobNetwork : NSObject  <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
27
 @interface RNFetchBlobNetwork : NSObject  <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
33
 
28
 
43
 @property (strong, nonatomic) CompletionHander fileTaskCompletionHandler;
38
 @property (strong, nonatomic) CompletionHander fileTaskCompletionHandler;
44
 @property (strong, nonatomic) DataTaskCompletionHander dataTaskCompletionHandler;
39
 @property (strong, nonatomic) DataTaskCompletionHander dataTaskCompletionHandler;
45
 @property (nullable, nonatomic) NSError * error;
40
 @property (nullable, nonatomic) NSError * error;
46
-@property (nullable, nonatomic) NSMutableArray * redirects;
47
-
48
-@property (nonatomic) BOOL respFile;
49
-@property (nonatomic) BOOL isNewPart;
50
-@property (nonatomic) BOOL isIncrement;
51
-@property (nullable, nonatomic) NSMutableData * partBuffer;
52
-@property (nullable, nonatomic) NSString * destPath;
53
-@property (nullable, nonatomic) NSOutputStream * writeStream;
54
-@property (nonatomic) long bodyLength;
55
-@property (nullable, nonatomic) NSMutableDictionary * respInfo;
56
-@property (nonatomic) NSInteger respStatus;
57
-@property (nonatomic) ResponseFormat responseFormat;
58
-@property ( nonatomic) BOOL followRedirect;
59
 
41
 
60
 
42
 
61
 + (NSMutableDictionary  * _Nullable ) normalizeHeaders:(NSDictionary * _Nullable)headers;
43
 + (NSMutableDictionary  * _Nullable ) normalizeHeaders:(NSDictionary * _Nullable)headers;

+ 26
- 14
ios/RNFetchBlobNetwork.m Datei anzeigen

61
 }
61
 }
62
 
62
 
63
 
63
 
64
+typedef NS_ENUM(NSUInteger, ResponseFormat) {
65
+    UTF8,
66
+    BASE64,
67
+    AUTO
68
+};
69
+
70
+
71
+@interface RNFetchBlobNetwork ()
72
+{
73
+    BOOL * respFile;
74
+    BOOL isNewPart;
75
+    BOOL * isIncrement;
76
+    NSMutableData * partBuffer;
77
+    NSString * destPath;
78
+    NSOutputStream * writeStream;
79
+    long bodyLength;
80
+    NSMutableDictionary * respInfo;
81
+    NSInteger respStatus;
82
+    NSMutableArray * redirects;
83
+    ResponseFormat responseFormat;
84
+    BOOL * followRedirect;
85
+}
86
+
87
+@end
64
 
88
 
65
 @implementation RNFetchBlobNetwork
89
 @implementation RNFetchBlobNetwork
66
 
90
 
72
 @synthesize callback;
96
 @synthesize callback;
73
 @synthesize bridge;
97
 @synthesize bridge;
74
 @synthesize options;
98
 @synthesize options;
75
-@synthesize redirects;
76
 @synthesize fileTaskCompletionHandler;
99
 @synthesize fileTaskCompletionHandler;
77
 @synthesize dataTaskCompletionHandler;
100
 @synthesize dataTaskCompletionHandler;
78
 @synthesize error;
101
 @synthesize error;
79
 
102
 
80
-@synthesize respFile;
81
-@synthesize isNewPart;
82
-@synthesize isIncrement;
83
-@synthesize partBuffer;
84
-@synthesize destPath;
85
-@synthesize writeStream;
86
-@synthesize bodyLength;
87
-@synthesize respInfo;
88
-@synthesize respStatus;
89
-@synthesize responseFormat;
90
-@synthesize followRedirect;
91
-
92
 
103
 
93
 // constructor
104
 // constructor
94
 - (id)init {
105
 - (id)init {
240
     UIBackgroundTaskIdentifier tid = [app beginBackgroundTaskWithName:taskId expirationHandler:^{
251
     UIBackgroundTaskIdentifier tid = [app beginBackgroundTaskWithName:taskId expirationHandler:^{
241
         NSLog([NSString stringWithFormat:@"session %@ expired", taskId ]);
252
         NSLog([NSString stringWithFormat:@"session %@ expired", taskId ]);
242
         [expirationTable setObject:task forKey:taskId];
253
         [expirationTable setObject:task forKey:taskId];
243
-        [app endBackgroundTask:tid];
254
+        // comment out this one as it might cause app crash #271
255
+//        [app endBackgroundTask:tid];
244
     }];
256
     }];
245
 
257
 
246
 }
258
 }

+ 49
- 26
ios/RNFetchBlobReqBuilder.m Datei anzeigen

51
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
51
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
52
         __block NSMutableData * postData = [[NSMutableData alloc] init];
52
         __block NSMutableData * postData = [[NSMutableData alloc] init];
53
         // combine multipart/form-data body
53
         // combine multipart/form-data body
54
-        [[self class] buildFormBody:form boundary:boundary onComplete:^(NSData *formData) {
55
-            if(formData != nil) {
56
-                [postData appendData:formData];
57
-                // close form data
58
-                [postData appendData: [[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
59
-                [request setHTTPBody:postData];
54
+        [[self class] buildFormBody:form boundary:boundary onComplete:^(NSData *formData, BOOL hasError) {
55
+            if(hasError)
56
+            {
57
+                onComplete(nil, nil);
58
+            }
59
+            else
60
+            {
61
+                if(formData != nil)
62
+                {
63
+                    [postData appendData:formData];
64
+                    // close form data
65
+                    [postData appendData: [[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
66
+                    [request setHTTPBody:postData];
67
+                }
68
+                // set content-length
69
+                [mheaders setValue:[NSString stringWithFormat:@"%lu",[postData length]] forKey:@"Content-Length"];
70
+                [mheaders setValue:@"100-continue" forKey:@"Expect"];
71
+                // appaned boundary to content-type
72
+                [mheaders setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forKey:@"content-type"];
73
+                [request setHTTPMethod: method];
74
+                [request setAllHTTPHeaderFields:mheaders];
75
+                onComplete(request, [formData length]);
60
             }
76
             }
61
-            // set content-length
62
-            [mheaders setValue:[NSString stringWithFormat:@"%lu",[postData length]] forKey:@"Content-Length"];
63
-            [mheaders setValue:@"100-continue" forKey:@"Expect"];
64
-            // appaned boundary to content-type
65
-            [mheaders setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forKey:@"content-type"];
66
-            [request setHTTPMethod: method];
67
-            [request setAllHTTPHeaderFields:mheaders];
68
-            onComplete(request, [formData length]);
69
         }];
77
         }];
70
 
78
 
71
     });
79
     });
91
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
99
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
92
         NSMutableData * blobData;
100
         NSMutableData * blobData;
93
         long size = -1;
101
         long size = -1;
94
-        // if method is POST or PUT, convert data string format
95
-        if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
102
+        // if method is POST, PUT or PATCH, convert data string format
103
+        if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"] || [[method lowercaseString] isEqualToString:@"patch"]) {
96
             // generate octet-stream body
104
             // generate octet-stream body
97
             if(body != nil) {
105
             if(body != nil) {
98
                 __block NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
106
                 __block NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
109
                     orgPath = [RNFetchBlobFS getPathOfAsset:orgPath];
117
                     orgPath = [RNFetchBlobFS getPathOfAsset:orgPath];
110
                     if([orgPath hasPrefix:AL_PREFIX])
118
                     if([orgPath hasPrefix:AL_PREFIX])
111
                     {
119
                     {
112
-                        [RNFetchBlobFS readFile:orgPath encoding:@"utf8" resolver:nil rejecter:nil onComplete:^(NSData *content) {
113
-                            [request setHTTPBody:content];
114
-                            [request setHTTPMethod: method];
115
-                            [request setAllHTTPHeaderFields:mheaders];
116
-                            onComplete(request, [content length]);
120
+                        
121
+                        [RNFetchBlobFS readFile:orgPath encoding:nil onComplete:^(NSData *content, NSString * err) {
122
+                            if(err != nil)
123
+                            {
124
+                                onComplete(nil, nil);
125
+                            }
126
+                            else
127
+                            {
128
+                                [request setHTTPBody:content];
129
+                                [request setHTTPMethod: method];
130
+                                [request setAllHTTPHeaderFields:mheaders];
131
+                                onComplete(request, [content length]);
132
+                            }
117
                         }];
133
                         }];
134
+                        
118
                         return;
135
                         return;
119
                     }
136
                     }
120
                     size = [[[NSFileManager defaultManager] attributesOfItemAtPath:orgPath error:nil] fileSize];
137
                     size = [[[NSFileManager defaultManager] attributesOfItemAtPath:orgPath error:nil] fileSize];
161
     });
178
     });
162
 }
179
 }
163
 
180
 
164
-+(void) buildFormBody:(NSArray *)form boundary:(NSString *)boundary onComplete:(void(^)(NSData * formData))onComplete
181
++(void) buildFormBody:(NSArray *)form boundary:(NSString *)boundary onComplete:(void(^)(NSData * formData, BOOL hasError))onComplete
165
 {
182
 {
166
     __block NSMutableData * formData = [[NSMutableData alloc] init];
183
     __block NSMutableData * formData = [[NSMutableData alloc] init];
167
     if(form == nil)
184
     if(form == nil)
168
-        onComplete(nil);
185
+        onComplete(nil, NO);
169
     else
186
     else
170
     {
187
     {
171
         __block int i = 0;
188
         __block int i = 0;
202
                     {
219
                     {
203
                         NSString * orgPath = [content substringFromIndex:[FILE_PREFIX length]];
220
                         NSString * orgPath = [content substringFromIndex:[FILE_PREFIX length]];
204
                         orgPath = [RNFetchBlobFS getPathOfAsset:orgPath];
221
                         orgPath = [RNFetchBlobFS getPathOfAsset:orgPath];
205
-                        [RNFetchBlobFS readFile:orgPath encoding:@"utf8" resolver:nil rejecter:nil onComplete:^(NSData *content) {
222
+
223
+                        [RNFetchBlobFS readFile:orgPath encoding:nil onComplete:^(NSData *content, NSString * err) {
224
+                            if(err != nil)
225
+                            {
226
+                                onComplete(formData, YES);
227
+                                return;
228
+                            }
206
                             NSString * filename = [field valueForKey:@"filename"];
229
                             NSString * filename = [field valueForKey:@"filename"];
207
                             [formData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
230
                             [formData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
208
                             [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name, filename] dataUsingEncoding:NSUTF8StringEncoding]];
231
                             [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name, filename] dataUsingEncoding:NSUTF8StringEncoding]];
217
                             }
240
                             }
218
                             else
241
                             else
219
                             {
242
                             {
220
-                                onComplete(formData);
243
+                                onComplete(formData, NO);
221
                                 getFieldData = nil;
244
                                 getFieldData = nil;
222
                             }
245
                             }
223
                         }];
246
                         }];
242
             }
265
             }
243
             else
266
             else
244
             {
267
             {
245
-                onComplete(formData);
268
+                onComplete(formData, NO);
246
                 getFieldData = nil;
269
                 getFieldData = nil;
247
             }
270
             }
248
 
271
 

+ 2
- 2
package.json Datei anzeigen

1
 {
1
 {
2
   "name": "react-native-fetch-blob",
2
   "name": "react-native-fetch-blob",
3
-  "version": "0.10.3-beta.1",
3
+  "version": "0.10.4",
4
   "description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
4
   "description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
5
   "main": "index.js",
5
   "main": "index.js",
6
   "scripts": {
6
   "scripts": {
59
     "smartt <github@eriksmartt.com>",
59
     "smartt <github@eriksmartt.com>",
60
     ""
60
     ""
61
   ]
61
   ]
62
-}
62
+}

+ 1
- 1
polyfill/Blob.js Datei anzeigen

113
           formArray.push('\r\n--'+boundary+'\r\n')
113
           formArray.push('\r\n--'+boundary+'\r\n')
114
           let part = parts[i]
114
           let part = parts[i]
115
           for(let j in part.headers) {
115
           for(let j in part.headers) {
116
-            formArray.push(j + ': ' +part.headers[j] + ';\r\n')
116
+            formArray.push(j + ': ' +part.headers[j] + '\r\n')
117
           }
117
           }
118
           formArray.push('\r\n')
118
           formArray.push('\r\n')
119
           if(part.isRNFetchBlobPolyfill)
119
           if(part.isRNFetchBlobPolyfill)

+ 0
- 2
polyfill/Fetch.js Datei anzeigen

32
       options.headers['Content-Type'] = ctype || ctypeH
32
       options.headers['Content-Type'] = ctype || ctypeH
33
       options.headers['content-type'] = ctype || ctypeH
33
       options.headers['content-type'] = ctype || ctypeH
34
       options.method = options.method || 'GET'
34
       options.method = options.method || 'GET'
35
-
36
       if(body) {
35
       if(body) {
37
         // When the request body is an instance of FormData, create a Blob cache
36
         // When the request body is an instance of FormData, create a Blob cache
38
         // to upload the body.
37
         // to upload the body.
55
         else
54
         else
56
           promise = Promise.resolve(body)
55
           promise = Promise.resolve(body)
57
       }
56
       }
58
-
59
       // task is a progress reportable and cancellable Promise, however,
57
       // task is a progress reportable and cancellable Promise, however,
60
       // task.then is not, so we have to extend task.then with progress and
58
       // task.then is not, so we have to extend task.then with progress and
61
       // cancel function
59
       // cancel function