Ben Hsieh 8 年 前
コミット
ee0f38e380

+ 10
- 1
src/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java ファイルの表示

@@ -12,7 +12,6 @@ import java.util.Map;
12 12
 
13 13
 public class RNFetchBlob extends ReactContextBaseJavaModule {
14 14
 
15
-    String filePathPrefix = "RNFetchBlob-file://";
16 15
     static ReactApplicationContext RCTContext;
17 16
 
18 17
     public RNFetchBlob(ReactApplicationContext reactContext) {
@@ -165,6 +164,16 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
165 164
         RNFetchBlobFS.slice(src, dest, start, end, encode, callback);
166 165
     }
167 166
 
167
+    @ReactMethod
168
+    public void enableProgressReport(String taskId) {
169
+        RNFetchBlobReq.progressReport.put(taskId, true);
170
+    }
171
+
172
+    @ReactMethod
173
+    public void enableUploadProgressReport(String taskId) {
174
+        RNFetchBlobReq.uploadProgressReport.put(taskId, true);
175
+    }
176
+
168 177
     @ReactMethod
169 178
     public void fetchBlob(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
170 179
         new RNFetchBlobReq(options, taskId, method, url, headers, body, null, callback).run();

+ 5
- 3
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java ファイルの表示

@@ -335,9 +335,11 @@ public class RNFetchBlobBody extends RequestBody{
335 335
             args.putString("written", String.valueOf(bytesWritten));
336 336
             args.putString("total", String.valueOf(contentLength));
337 337
 
338
-            // emit event to js context
339
-            RNFetchBlob.RCTContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
340
-                    .emit(RNFetchBlobConst.EVENT_UPLOAD_PROGRESS, args);
338
+            if(RNFetchBlobReq.isReportUploadProgress(mTaskId)) {
339
+                // emit event to js context
340
+                RNFetchBlob.RCTContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
341
+                        .emit(RNFetchBlobConst.EVENT_UPLOAD_PROGRESS, args);
342
+            }
341 343
         }
342 344
     }
343 345
 }

+ 31
- 5
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java ファイルの表示

@@ -64,7 +64,9 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
64 64
         FileStorage
65 65
     };
66 66
 
67
-    static HashMap<String, Call> taskTable = new HashMap<>();
67
+    public static HashMap<String, Call> taskTable = new HashMap<>();
68
+    static HashMap<String, Boolean> progressReport = new HashMap<>();
69
+    static HashMap<String, Boolean> uploadProgressReport = new HashMap<>();
68 70
 
69 71
     MediaType contentType = RNFetchBlobConst.MIME_OCTET;
70 72
     ReactApplicationContext ctx;
@@ -81,8 +83,10 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
81 83
     long downloadManagerId;
82 84
     RequestType requestType;
83 85
     ResponseType responseType;
84
-    boolean timeout = false;
85 86
     WritableMap respInfo;
87
+    boolean timeout = false;
88
+    public boolean reportProgress = false;
89
+    public boolean reportUploadProgress = false;
86 90
 
87 91
     public RNFetchBlobReq(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, ReadableArray arrayBody, final Callback callback) {
88 92
         this.method = method;
@@ -304,7 +308,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
304 308
             }
305 309
 
306 310
             OkHttpClient client = clientBuilder.build();
307
-            Call call = client.newCall(req);
311
+            Call call =  client.newCall(req);
308 312
             taskTable.put(taskId, call);
309 313
             call.enqueue(new okhttp3.Callback() {
310 314
 
@@ -321,6 +325,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
321 325
                     }
322 326
                     else
323 327
                         callback.invoke(e.getLocalizedMessage(), respInfo, null);
328
+                    removeTaskInfo();
324 329
                 }
325 330
 
326 331
                 @Override
@@ -356,6 +361,18 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
356 361
         }
357 362
     }
358 363
 
364
+    /**
365
+     * Remove cached information of the HTTP task
366
+     */
367
+    private void removeTaskInfo() {
368
+        if(taskTable.containsKey(taskId))
369
+            taskTable.remove(taskId);
370
+        if(uploadProgressReport.containsKey(taskId))
371
+            uploadProgressReport.remove(taskId);
372
+        if(progressReport.containsKey(taskId))
373
+            progressReport.remove(taskId);
374
+    }
375
+
359 376
     /**
360 377
      * Send response data back to javascript context.
361 378
      * @param resp OkHttp response object
@@ -408,8 +425,17 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
408 425
                 }
409 426
                 break;
410 427
         }
411
-        if(taskTable.containsKey(taskId))
412
-            taskTable.remove(taskId);
428
+        removeTaskInfo();
429
+    }
430
+
431
+    public static boolean isReportProgress(String taskId) {
432
+        if(!progressReport.containsKey(taskId)) return false;
433
+        return progressReport.get(taskId);
434
+    }
435
+
436
+    public static boolean isReportUploadProgress(String taskId) {
437
+        if(!uploadProgressReport.containsKey(taskId)) return false;
438
+        return uploadProgressReport.get(taskId);
413 439
     }
414 440
 
415 441
     private WritableMap getResponseInfo(Response resp) {

+ 9
- 6
src/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobDefaultResp.java ファイルの表示

@@ -1,6 +1,7 @@
1 1
 package com.RNFetchBlob.Response;
2 2
 
3 3
 import com.RNFetchBlob.RNFetchBlob;
4
+import com.RNFetchBlob.RNFetchBlobReq;
4 5
 import com.facebook.react.bridge.Arguments;
5 6
 import com.facebook.react.bridge.ReactApplicationContext;
6 7
 import com.facebook.react.bridge.WritableMap;
@@ -64,12 +65,14 @@ public class RNFetchBlobDefaultResp extends ResponseBody {
64 65
 
65 66
             long read =  mOriginalSource.read(sink, byteCount);
66 67
             bytesRead += read > 0 ? read : 0;
67
-            WritableMap args = Arguments.createMap();
68
-            args.putString("taskId", mTaskId);
69
-            args.putString("written", String.valueOf(bytesRead));
70
-            args.putString("total", String.valueOf(contentLength()));
71
-            rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
72
-                    .emit("RNFetchBlobProgress", args);
68
+            if(RNFetchBlobReq.isReportProgress(mTaskId)) {
69
+                WritableMap args = Arguments.createMap();
70
+                args.putString("taskId", mTaskId);
71
+                args.putString("written", String.valueOf(bytesRead));
72
+                args.putString("total", String.valueOf(contentLength()));
73
+                rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
74
+                        .emit("RNFetchBlobProgress", args);
75
+            }
73 76
             return read;
74 77
         }
75 78
 

+ 4
- 1
src/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java ファイルの表示

@@ -2,6 +2,7 @@ package com.RNFetchBlob.Response;
2 2
 
3 3
 import android.util.Log;
4 4
 
5
+import com.RNFetchBlob.RNFetchBlobReq;
5 6
 import com.facebook.react.bridge.Arguments;
6 7
 import com.facebook.react.bridge.ReactApplicationContext;
7 8
 import com.facebook.react.bridge.WritableMap;
@@ -69,8 +70,10 @@ public class RNFetchBlobFileResp extends ResponseBody {
69 70
             long read = originalBody.byteStream().read(bytes, 0, (int) byteCount);
70 71
             bytesDownloaded += read > 0 ? read : 0;
71 72
             Log.i("bytes downloaded", String.valueOf(byteCount) +"/"+ String.valueOf(read) + "=" + String.valueOf(bytesDownloaded));
72
-            if(read > 0) {
73
+            if(read > 0 ) {
73 74
                 ofStream.write(bytes, 0, (int) read);
75
+            }
76
+            if(RNFetchBlobReq.isReportProgress(mTaskId)) {
74 77
                 WritableMap args = Arguments.createMap();
75 78
                 args.putString("taskId", mTaskId);
76 79
                 args.putString("written", String.valueOf(bytesDownloaded));

+ 2
- 0
src/index.js ファイルの表示

@@ -175,10 +175,12 @@ function fetch(...args:any):Promise {
175 175
   // method for register progress event handler and cancel request.
176 176
   promise.progress = (fn) => {
177 177
     promise.onProgress = fn
178
+    RNFetchBlob.enableProgressReport(taskId)
178 179
     return promise
179 180
   }
180 181
   promise.uploadProgress = (fn) => {
181 182
     promise.onUploadProgress = fn
183
+    RNFetchBlob.enableUploadProgressReport(taskId)
182 184
     return promise
183 185
   }
184 186
   promise.stateChange = (fn) => {

+ 8
- 0
src/ios/RNFetchBlob/RNFetchBlob.m ファイルの表示

@@ -358,6 +358,14 @@ RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBl
358 358
 
359 359
 }
360 360
 
361
+RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId {
362
+    [RNFetchBlobNetwork enableProgressReport:taskId];
363
+})
364
+
365
+RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId {
366
+    [RNFetchBlobNetwork enableUploadProgress:taskId];
367
+})
368
+
361 369
 RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(NSNumber *)start end:(NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
362 370
 {
363 371
     [RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];

+ 3
- 0
src/ios/RNFetchBlobConst.h ファイルの表示

@@ -36,6 +36,9 @@ extern NSString *const FS_EVENT_END;
36 36
 extern NSString *const FS_EVENT_WARN;
37 37
 extern NSString *const FS_EVENT_ERROR;
38 38
 
39
+extern NSString *const KEY_REPORT_PROGRESS;
40
+extern NSString *const KEY_REPORT_UPLOAD_PROGRESS;
41
+
39 42
 
40 43
 
41 44
 #endif /* RNFetchBlobConst_h */

+ 3
- 0
src/ios/RNFetchBlobConst.m ファイルの表示

@@ -30,3 +30,6 @@ extern NSString *const FS_EVENT_DATA = @"data";
30 30
 extern NSString *const FS_EVENT_END = @"end";
31 31
 extern NSString *const FS_EVENT_WARN = @"warn";
32 32
 extern NSString *const FS_EVENT_ERROR = @"error";
33
+
34
+extern NSString *const KEY_REPORT_PROGRESS = @"reportProgress";
35
+extern NSString *const KEY_REPORT_UPLOAD_PROGRESS = @"reportUploadProgress";

+ 2
- 0
src/ios/RNFetchBlobNetwork.h ファイルの表示

@@ -36,6 +36,8 @@ typedef void(^DataTaskCompletionHander) (NSData * _Nullable resp, NSURLResponse
36 36
 
37 37
 + (NSMutableDictionary  * _Nullable ) normalizeHeaders:(NSDictionary * _Nullable)headers;
38 38
 + (void) cancelRequest:(NSString *)taskId;
39
++ (void) enableProgressReport:(NSString *) taskId;
40
++ (void) enableUploadProgress:(NSString *) taskId;
39 41
 - (void) sendRequest:(NSDictionary  * _Nullable )options contentLength:(long)contentLength bridge:(RCTBridge * _Nullable)bridgeRef taskId:(NSString * _Nullable)taskId withRequest:(NSURLRequest * _Nullable)req callback:(_Nullable RCTResponseSenderBlock) callback;
40 42
 
41 43
 

+ 49
- 20
src/ios/RNFetchBlobNetwork.m ファイルの表示

@@ -24,6 +24,8 @@
24 24
 ////////////////////////////////////////
25 25
 
26 26
 NSMutableDictionary * taskTable;
27
+NSMutableDictionary * progressTable;
28
+NSMutableDictionary * uploadProgressTable;
27 29
 
28 30
 @interface RNFetchBlobNetwork ()
29 31
 {
@@ -61,12 +63,30 @@ NSOperationQueue *taskQueue;
61 63
     if(taskTable == nil) {
62 64
         taskTable = [[NSMutableDictionary alloc] init];
63 65
     }
66
+    if(progressTable == nil)
67
+    {
68
+        progressTable = [[NSMutableDictionary alloc] init];
69
+    }
70
+    if(uploadProgressTable == nil)
71
+    {
72
+        uploadProgressTable = [[NSMutableDictionary alloc] init];
73
+    }
64 74
     return self;
65 75
 }
66 76
 
77
++ (void) enableProgressReport:(NSString *) taskId
78
+{
79
+    [progressTable setValue:@YES forKey:taskId];
80
+}
81
+
82
++ (void) enableUploadProgress:(NSString *) taskId
83
+{
84
+    [uploadProgressTable setValue:@YES forKey:taskId];
85
+}
67 86
 
68 87
 // removing case from headers
69
-+ (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers {
88
++ (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers
89
+{
70 90
 
71 91
     NSMutableDictionary * mheaders = [[NSMutableDictionary alloc]init];
72 92
     for(NSString * key in headers) {
@@ -149,7 +169,7 @@ NSOperationQueue *taskQueue;
149 169
         respFile = NO;
150 170
     }
151 171
     NSURLSessionDataTask * task = [session dataTaskWithRequest:req];
152
-    [taskTable setValue:task forKey:taskId];
172
+    [taskTable setValue:@{ @"task": task, KEY_REPORT_PROGRESS : @NO, KEY_REPORT_UPLOAD_PROGRESS : @NO} forKey:taskId];
153 173
     [task resume];
154 174
 
155 175
     // network status indicator
@@ -248,15 +268,18 @@ NSOperationQueue *taskQueue;
248 268
     {
249 269
         [writeStream write:[data bytes] maxLength:[data length]];
250 270
     }
251
-
252
-    [self.bridge.eventDispatcher
253
-     sendDeviceEventWithName:@"RNFetchBlobProgress"
254
-     body:@{
255
-            @"taskId": taskId,
256
-            @"written": [NSString stringWithFormat:@"%d", receivedBytes],
257
-            @"total": [NSString stringWithFormat:@"%d", expectedBytes]
258
-            }
259
-     ];
271
+    
272
+    if([progressTable valueForKey:taskId] == @YES)
273
+    {
274
+        [self.bridge.eventDispatcher
275
+         sendDeviceEventWithName:@"RNFetchBlobProgress"
276
+         body:@{
277
+                @"taskId": taskId,
278
+                @"written": [NSString stringWithFormat:@"%d", receivedBytes],
279
+                @"total": [NSString stringWithFormat:@"%d", expectedBytes]
280
+                }
281
+         ];
282
+    }
260 283
 
261 284
 }
262 285
 
@@ -286,24 +309,30 @@ NSOperationQueue *taskQueue;
286 309
                    [respData base64EncodedStringWithOptions:0]
287 310
                    ]);
288 311
     }
312
+    
313
+    [taskTable removeObjectForKey:taskId];
314
+    [uploadProgressTable removeObjectForKey:taskId];
315
+    [progressTable removeObjectForKey:taskId];
289 316
 }
290 317
 
291 318
 // upload progress handler
292 319
 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesWritten totalBytesExpectedToSend:(int64_t)totalBytesExpectedToWrite
293 320
 {
294
-    [self.bridge.eventDispatcher
295
-     sendDeviceEventWithName:@"RNFetchBlobProgress-upload"
296
-     body:@{
297
-            @"taskId": taskId,
298
-            @"written": [NSString stringWithFormat:@"%d", totalBytesWritten],
299
-            @"total": [NSString stringWithFormat:@"%d", bodyLength]
300
-            }
301
-     ];
321
+    if([uploadProgressTable valueForKey:taskId] == @YES) {
322
+        [self.bridge.eventDispatcher
323
+         sendDeviceEventWithName:@"RNFetchBlobProgress-upload"
324
+         body:@{
325
+                @"taskId": taskId,
326
+                @"written": [NSString stringWithFormat:@"%d", totalBytesWritten],
327
+                @"total": [NSString stringWithFormat:@"%d", bodyLength]
328
+                }
329
+         ];
330
+    }
302 331
 }
303 332
 
304 333
 + (void) cancelRequest:(NSString *)taskId
305 334
 {
306
-    NSURLSessionDataTask * task = (NSURLSessionDataTask *)[taskTable objectForKey:taskId];
335
+    NSURLSessionDataTask * task = (NSURLSessionDataTask *)[[taskTable objectForKey:taskId] objectForKey:@"task"];
307 336
     if(task != nil && task.state == NSURLSessionTaskStateRunning)
308 337
         [task cancel];
309 338
 }