2

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.

Pratik Patel
  • 1,393
  • 12
  • 18
  • can you get solution of this ? – Dhaval Bhadania Jul 19 '16 at 05:33
  • You can use above code. Its working fine. – Pratik Patel Jul 19 '16 at 05:37
  • i want in some interval upload data(in background mode application) on server is it possible ?? if yes can you give suggestion or sample ? is it working upload in back ground after 3 min of App background mode also ? – Dhaval Bhadania Jul 19 '16 at 05:57
  • Yes, its working. Sorry, but i have not that code which is working properly. I have left my previous company. You will not found this kind of code any where on net. – Pratik Patel Jul 19 '16 at 06:08
  • can you tell me how to do in interval like every 15 min upload data on server using NSURLSession ? – Dhaval Bhadania Jul 19 '16 at 06:41
  • You can not perform any time interval when app is in back ground more than 3 min. If you want to do so then use back ground fetch methods and make a dispatcher which returns any value to app. When any back ground fetch results received then app is awake for 10sec. In this 10sec you can start your task. – Pratik Patel Jul 19 '16 at 06:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117663/discussion-between-dhaval-bhadania-and-pratik-patel). – Dhaval Bhadania Jul 19 '16 at 07:03

0 Answers0