1111#import " RNFetchBlobFS.h"
1212#import " RNFetchBlobConst.h"
1313#import " RNFetchBlobReqBuilder.h"
14- #if __has_include(<React/RCTLog.h>)
15- #import < React/RCTLog.h>
16- #else
17- #import " RCTLog.h"
18- #endif
1914
2015#import " IOS7Polyfill.h"
2116#import < CommonCrypto/CommonDigest.h>
2217
23- NSMapTable * taskTable;
24-
25- __attribute__ ((constructor))
26- static void initialize_tables() {
27- if (taskTable == nil )
28- {
29- taskTable = [[NSMapTable alloc ] init ];
30- }
31- }
3218
3319typedef NS_ENUM (NSUInteger , ResponseFormat) {
3420 UTF8,
@@ -50,7 +36,6 @@ @interface RNFetchBlobRequest ()
5036 ResponseFormat responseFormat;
5137 BOOL followRedirect;
5238 BOOL backgroundTask;
53- BOOL uploadTask;
5439}
5540
5641@end
@@ -97,16 +82,6 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
9782 self.options = options;
9883
9984 backgroundTask = [[options valueForKey: @" IOSBackgroundTask" ] boolValue ];
100- uploadTask = [options valueForKey: @" IOSUploadTask" ] == nil ? NO : [[options valueForKey: @" IOSUploadTask" ] boolValue ];
101-
102- NSString * filepath = [options valueForKey: @" uploadFilePath" ];
103-
104- if (uploadTask && ![[NSFileManager defaultManager ] fileExistsAtPath: [NSURL URLWithString: filepath].path]) {
105- RCTLog (@" [RNFetchBlobRequest] sendRequest uploadTask file doesn't exist %@ " , filepath);
106- callback (@[@" uploadTask file doesn't exist" , @" " , [NSNull null ]]);
107- return ;
108- }
109-
11085 // when followRedirect not set in options, defaults to TRUE
11186 followRedirect = [options valueForKey: @" followRedirect" ] == nil ? YES : [[options valueForKey: @" followRedirect" ] boolValue ];
11287 isIncrement = [[options valueForKey: @" increment" ] boolValue ];
@@ -129,6 +104,7 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
129104
130105 NSString * path = [self .options valueForKey: CONFIG_FILE_PATH];
131106 NSString * key = [self .options valueForKey: CONFIG_KEY];
107+ NSURLSession * session;
132108
133109 bodyLength = contentLength;
134110
@@ -141,7 +117,6 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
141117 defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: taskId];
142118 }
143119
144-
145120 // request timeout, -1 if not set in options
146121 float timeout = [options valueForKey: @" timeout" ] == nil ? -1 : [[options valueForKey: @" timeout" ] floatValue ];
147122
@@ -150,7 +125,7 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
150125 }
151126
152127 defaultConfigObject.HTTPMaximumConnectionsPerHost = 10 ;
153- _session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: operationQueue];
128+ session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: operationQueue];
154129
155130 if (path || [self .options valueForKey: CONFIG_USE_TEMP]) {
156131 respFile = YES ;
@@ -182,19 +157,8 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
182157 respFile = NO ;
183158 }
184159
185- __block NSURLSessionTask * task;
186-
187- if (uploadTask)
188- {
189- task = [_session uploadTaskWithRequest: req fromFile: [NSURL URLWithString: filepath]];
190- }
191- else
192- {
193- task = [_session dataTaskWithRequest: req];
194- }
195-
196- [taskTable setObject: task forKey: taskId];
197- [task resume ];
160+ self.task = [session dataTaskWithRequest: req];
161+ [self .task resume ];
198162
199163 // network status indicator
200164 if ([[options objectForKey: CONFIG_INDICATOR] boolValue ]) {
@@ -218,7 +182,6 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
218182// set expected content length on response received
219183- (void ) URLSession : (NSURLSession *)session dataTask : (NSURLSessionDataTask *)dataTask didReceiveResponse : (NSURLResponse *)response completionHandler : (void (^)(NSURLSessionResponseDisposition ))completionHandler
220184{
221- NSLog (@" sess didReceiveResponse" );
222185 expectedBytes = [response expectedContentLength ];
223186
224187 NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
@@ -244,7 +207,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
244207
245208 partBuffer = [[NSMutableData alloc ] init ];
246209 completionHandler (NSURLSessionResponseAllow );
247-
210+
248211 return ;
249212 } else {
250213 self.isServerPush = [[respCType lowercaseString ] RNFBContainsString: @" multipart/x-mixed-replace;" ];
@@ -306,6 +269,42 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
306269 NSLog (@" oops" );
307270 }
308271
272+ if (respFile)
273+ {
274+ @try {
275+ NSFileManager * fm = [NSFileManager defaultManager ];
276+ NSString * folder = [destPath stringByDeletingLastPathComponent ];
277+
278+ if (![fm fileExistsAtPath: folder]) {
279+ [fm createDirectoryAtPath: folder withIntermediateDirectories: YES attributes: NULL error: nil ];
280+ }
281+
282+ // if not set overwrite in options, defaults to TRUE
283+ BOOL overwrite = [options valueForKey: @" overwrite" ] == nil ? YES : [[options valueForKey: @" overwrite" ] boolValue ];
284+ BOOL appendToExistingFile = [destPath RNFBContainsString: @" ?append=true" ];
285+
286+ appendToExistingFile = !overwrite;
287+
288+ // For solving #141 append response data if the file already exists
289+ // base on PR#139 @kejinliang
290+ if (appendToExistingFile) {
291+ destPath = [destPath stringByReplacingOccurrencesOfString: @" ?append=true" withString: @" " ];
292+ }
293+
294+ if (![fm fileExistsAtPath: destPath]) {
295+ [fm createFileAtPath: destPath contents: [[NSData alloc ] init ] attributes: nil ];
296+ }
297+
298+ writeStream = [[NSOutputStream alloc ] initToFileAtPath: destPath append: appendToExistingFile];
299+ [writeStream scheduleInRunLoop: [NSRunLoop currentRunLoop ] forMode: NSRunLoopCommonModes ];
300+ [writeStream open ];
301+ }
302+ @catch (NSException * ex)
303+ {
304+ NSLog (@" write file error" );
305+ }
306+ }
307+
309308 completionHandler (NSURLSessionResponseAllow );
310309}
311310
@@ -329,7 +328,11 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
329328 chunkString = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
330329 }
331330
332- [respData appendData: data];
331+ if (respFile) {
332+ [writeStream write: [data bytes ] maxLength: [data length ]];
333+ } else {
334+ [respData appendData: data];
335+ }
333336
334337 if (expectedBytes == 0 ) {
335338 return ;
@@ -350,16 +353,8 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
350353 }
351354}
352355
353- - (void ) cancelRequest : (NSString *)taskId
354- {
355- NSURLSessionDataTask * task = [taskTable objectForKey: taskId];
356- if (task != nil && task.state == NSURLSessionTaskStateRunning )
357- [task cancel ];
358- }
359-
360356- (void ) URLSession : (NSURLSession *)session didBecomeInvalidWithError : (nullable NSError *)error
361357{
362- RCTLog (@" [RNFetchBlobRequest] session didBecomeInvalidWithError %@ " , [error description ]);
363358 if ([session isEqual: session]) {
364359 session = nil ;
365360 }
@@ -368,7 +363,7 @@ - (void) URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable
368363
369364- (void ) URLSession : (NSURLSession *)session task : (NSURLSessionTask *)task didCompleteWithError : (NSError *)error
370365{
371- RCTLog ( @" [RNFetchBlobRequest] session didCompleteWithError %@ " , [error description ]);
366+
372367 self.error = error;
373368 NSString * errMsg;
374369 NSString * respStr;
@@ -421,17 +416,10 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCom
421416 respStr ?: [NSNull null ]
422417 ]);
423418
424- @synchronized (taskTable)
425- {
426- if ([taskTable objectForKey: taskId] == nil )
427- NSLog (@" object released by ARC." );
428- else
429- [taskTable removeObjectForKey: taskId];
430- }
431-
432419 respData = nil ;
433420 receivedBytes = 0 ;
434421 [session finishTasksAndInvalidate ];
422+
435423}
436424
437425// upload progress handler
@@ -442,7 +430,7 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSen
442430 }
443431
444432 NSNumber * now = [NSNumber numberWithFloat: ((float )totalBytesWritten/(float )totalBytesExpectedToWrite)];
445-
433+
446434 if ([self .uploadProgressConfig shouldReport: now]) {
447435 [self .bridge.eventDispatcher
448436 sendDeviceEventWithName: EVENT_PROGRESS_UPLOAD
@@ -468,19 +456,7 @@ - (void) URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthentica
468456
469457- (void ) URLSessionDidFinishEventsForBackgroundURLSession : (NSURLSession *)session
470458{
471- RCTLog (@" [RNFetchBlobRequest] session done in background" );
472- dispatch_async (dispatch_get_main_queue (), ^{
473- id <UIApplicationDelegate> appDelegate = [UIApplication sharedApplication ].delegate ;
474- SEL selector = NSSelectorFromString (@" backgroundTransferCompletionHandler" );
475- if ([appDelegate respondsToSelector: selector]) {
476- void (^completionHandler)() = [appDelegate performSelector: selector];
477- if (completionHandler != nil ) {
478- completionHandler ();
479- completionHandler = nil ;
480- }
481- }
482-
483- });
459+ NSLog (@" sess done in background" );
484460}
485461
486462- (void ) URLSession : (NSURLSession *)session task : (NSURLSessionTask *)task willPerformHTTPRedirection : (NSHTTPURLResponse *)response newRequest : (NSURLRequest *)request completionHandler : (void (^)(NSURLRequest * _Nullable))completionHandler
0 commit comments