diff --git a/ios/ReactNativeBlobUtilRequest.h b/ios/ReactNativeBlobUtilRequest.h index b3186df1..7867e232 100644 --- a/ios/ReactNativeBlobUtilRequest.h +++ b/ios/ReactNativeBlobUtilRequest.h @@ -20,7 +20,7 @@ #import "RCTBridgeModule.h" #endif -@interface ReactNativeBlobUtilRequest : NSObject +@interface ReactNativeBlobUtilRequest : NSObject @property (nullable, nonatomic) NSString * taskId; @property (nonatomic) long long expectedBytes; @@ -33,7 +33,7 @@ @property (nullable, nonatomic) NSError * error; @property (nullable, nonatomic) ReactNativeBlobUtilProgress *progressConfig; @property (nullable, nonatomic) ReactNativeBlobUtilProgress *uploadProgressConfig; -@property (nullable, nonatomic, weak) NSURLSessionDataTask *task; +@property (nullable, nonatomic, weak) NSURLSessionTask *task; - (void) sendRequest:(NSDictionary * _Nullable )options contentLength:(long)contentLength diff --git a/ios/ReactNativeBlobUtilRequest.mm b/ios/ReactNativeBlobUtilRequest.mm index 7792ce9b..ae6dd103 100644 --- a/ios/ReactNativeBlobUtilRequest.mm +++ b/ios/ReactNativeBlobUtilRequest.mm @@ -167,9 +167,15 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options respFile = NO; } - NSURLSessionDataTask *task = [session dataTaskWithRequest:req]; - [task resume]; - self.task = task; + if(backgroundTask) { + NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:req]; + [task resume]; + self.task = task; + } else { + NSURLSessionDataTask *task = [session dataTaskWithRequest:req]; + [task resume]; + self.task = task; + } // network status indicator if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) { @@ -188,6 +194,52 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options #pragma mark NSURLSession delegate methods +- (void)configureWriteStream { + if (respFile) + { + @try{ + NSFileManager * fm = [NSFileManager defaultManager]; + NSString * folder = [destPath stringByDeletingLastPathComponent]; + + if (![fm fileExistsAtPath:folder]) { + [fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil]; + } + + // if not set overwrite in options, defaults to TRUE + BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue]; + BOOL appendToExistingFile = [destPath containsString:@"?append=true"]; + + appendToExistingFile = !overwrite; + + // For solving #141 append response data if the file already exists + // base on PR#139 @kejinliang + if (appendToExistingFile) { + destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""]; + } + + if (![fm fileExistsAtPath:destPath]) { + [fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil]; + } + + writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile]; + [writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [writeStream open]; + } + @catch(NSException * ex) + { + NSLog(@"write file error"); + } + } +} + +- (void)processData:(NSData *)data { + if (respFile && ![self ShouldTransformFile]) { + [writeStream write:(const uint8_t *)[data bytes] maxLength:[data length]]; + } else { + [respData appendData:data]; + } +} + #pragma mark - Received Response // set expected content length on response received @@ -278,41 +330,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat NSLog(@"oops"); } - if (respFile) - { - @try{ - NSFileManager * fm = [NSFileManager defaultManager]; - NSString * folder = [destPath stringByDeletingLastPathComponent]; - - if (![fm fileExistsAtPath:folder]) { - [fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil]; - } - - // if not set overwrite in options, defaults to TRUE - BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue]; - BOOL appendToExistingFile = [destPath containsString:@"?append=true"]; - - appendToExistingFile = !overwrite; - - // For solving #141 append response data if the file already exists - // base on PR#139 @kejinliang - if (appendToExistingFile) { - destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""]; - } - - if (![fm fileExistsAtPath:destPath]) { - [fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil]; - } - - writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile]; - [writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; - [writeStream open]; - } - @catch(NSException * ex) - { - NSLog(@"write file error"); - } - } + [self configureWriteStream]; completionHandler(NSURLSessionResponseAllow); } @@ -339,11 +357,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat // If we need to process the data, we defer writing into the file until the we have all the data, at which point // we can perform the processing and then write into the file - if (respFile && ![self ShouldTransformFile]) { - [writeStream write:(const uint8_t *)[data bytes] maxLength:[data length]]; - } else { - [respData appendData:data]; - } + [self processData:data]; if (expectedBytes == 0) { return; @@ -535,5 +549,36 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPe } } +// NSURLSessionDownloadTask delegates + +#pragma mark NSURLSessionDownloadTask delegate methods + +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { + + NSFileManager *fm = [NSFileManager defaultManager]; + NSData *data = [fm contentsAtPath:location.path]; + + [self configureWriteStream]; + + [self processData:data]; + +} + +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { + if (totalBytesExpectedToWrite == 0) { + return; + } + + NSNumber * now =[NSNumber numberWithFloat:((float)totalBytesWritten/(float)totalBytesExpectedToWrite)]; + if ([self.progressConfig shouldReport:now]) { + [self.baseModule emitEventDict:EVENT_PROGRESS + body:@{ + @"taskId": taskId, + @"written": [NSString stringWithFormat:@"%lld", (long long) totalBytesWritten], + @"total": [NSString stringWithFormat:@"%lld", (long long) totalBytesExpectedToWrite] + } + ]; + } +} @end