i am uploading multiple files using NSURLSessionUploadTask. I want to run same process in back ground and it works fine for current file. App is not suspended until current file got uploaded successfully. Now, when second files comes to upload, it not start uploading process until i again launch or app became active. Uploading is not falling in between thats good. Is there any way to start next uploading process when first finishes. Second uploading is start also in back ground but that works upto 3 min from app goes in back ground. Here i shows my code:
AppDelegate.h
@property (nonatomic, copy) void(^backgroundTransferCompletionHandler)();
AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application{
__block UIBackgroundTaskIdentifier backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Background Time:%f",[[UIApplication sharedApplication] backgroundTimeRemaining]);
[[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier];
backgroundTaskIdentifier = backgroundTaskIdentifier;
`enter code here`}];
}
-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
self.backgroundTransferCompletionHandler = completionHandler;
NSLog(@"handleEventsForBackgroundURLSession called");
}
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
AppDelegate *appDelegate2 = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(@"URLSessionDidFinishEventsForBackgroundURLSession call in app delegate");
[session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
NSLog(@"uploadTasks: %@",uploadTasks);
if ([uploadTasks count] == 0) {
if (appDelegate2.backgroundTransferCompletionHandler != nil) {
// Copy locally the completion handler.
void(^completionHandler)() = appDelegate2.backgroundTransferCompletionHandler;
// Make nil the backgroundTransferCompletionHandler.
appDelegate2.backgroundTransferCompletionHandler = nil;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Call the completion handler to tell the system that there are no other background transfers.
completionHandler();
NSLog(@"All tasks are finished");
}];
}
}
else{
}
}];
}
UploadView.m
- (NSURLSession *)backgroundSession {
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSInteger randomNumber = arc4random() % 1000000;
// NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession%d",(int)randomNumber]];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"com.upload.myapp.BackgroundSession%d",(int)randomNumber]];
sessionConfiguration.sessionSendsLaunchEvents = YES;
sessionConfiguration.HTTPMaximumConnectionsPerHost = 1;
// Define the Upload task
[sessionConfiguration setHTTPAdditionalHeaders: @{@"Accept": @"text/html"}];
sessionConfiguration.timeoutIntervalForRequest = 600.0;
// sessionConfiguration.networkServiceType = NSURLNetworkServiceTypeBackground;
// sessionConfiguration.discretionary = YES;
sessionConfiguration.allowsCellularAccess = YES;
session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
});
return session;
}
ViewDidLoad(){
....
self.uploadSession = [self backgroundSession];
....}
-UploadStart(){//here i am calling this function in loop. When first file got uploaded, control comes here for second task and then upload should continue.
self.uploadTask = [self.uploadSession uploadTaskWithRequest:requestUpload fromFile:[NSURL fileURLWithPath:tmpfile]]; // self.uploadTask is an object of NSURLSessionUploadTask
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
NSLog(@"didReceiveData Task: %@ upload complete", dataTask);
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) self.uploadTask.response;
if (httpResp.statusCode == 200) {
uploadedFiles++; //an int value
if(uploadedFiles==arrUpload.count){
//all files uploaded here
}
else{
//upload next file from here
}
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
}
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
NSLog(@"URLSessionDidFinishEventsForBackgroundURLSession called");
AppDelegate *appDelegate2 = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate2.backgroundTransferCompletionHandler != nil) {
// Copy locally the completion handler.
void(^completionHandler)() = appDelegate2.backgroundTransferCompletionHandler;
// Make nil the backgroundTransferCompletionHandler.
appDelegate2.backgroundTransferCompletionHandler = nil;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Call the completion handler to tell the system that there are no other background transfers.
completionHandler();
NSLog(@"All tasks are finished");
}];
}
}
Above code is completely working, but having problem of next file is not start to upload in back ground after 3 min of App background mode.
Any help will be appreciate. Thanks in advance... For more explanation contact me.
来源:https://stackoverflow.com/questions/32647582/upload-file-with-nsurlsessionuploadtask-in-back-ground