Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

handleEventsForBackgroundURLSession never called when a downloadTask finished

I am using AFURLSessionManager, and set the manager as a singleton instance.

- (AFURLSessionManager *)backgroundSession
{
    static AFURLSessionManager *backgroundSession = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.testBackground.BackgroundDownload.BackgroundSession1234"];
    backgroundSession = [[AFURLSessionManager alloc]initWithSessionConfiguration:config];
    [backgroundSession setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite){
        NSLog(@"i am downloading my id = %d progress= %f",downloadTask.taskIdentifier, totalBytesWritten*1.0/totalBytesExpectedToWrite);
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    }];
    [backgroundSession setDownloadTaskDidFinishDownloadingBlock:^NSURL *(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location){
        NSLog(@"download finished");
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        return location;

    }];
    });
    return backgroundSession;
}
//assign a download task
NSURLSessionDownloadTask *task = [manager1 downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        return targetPath;
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    NSLog("%download success");
}];
[task resume];

I found that when I switch the app to the background the download task is running but when it was finished, the system call handleEventsForBackgroundURLSession will never be called.I am feeling that I have missed some setting or options. Any idea will be useful for me, thanks a lot.

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler;
like image 838
snorlax Avatar asked Dec 05 '13 02:12

snorlax


2 Answers

You probably have figured this out already but anyway, the exact same thing has happened to me while writing some test code to play with the background transfer service APIs (without AFNetworking). The solution was simply to change the identifier string for my background session configuration. Somehow the one I was using got bugged and the system wouldn't trigger the handleEventsForBackgroundURLSession callback. And not even restarting the device fixes it... however just changing the identifier does.

My theory is that my code created multiple instances of NSURLSession with the same configuration, which Apple clearly advices against (they say in the documentation that it has an undefined behavior if you do). I was obtaining the NSURLSessionConfiguration in the view controller's viewDidLoad method without a dispatch_once block, so it's certainly plausible that that happened.

like image 155
Oscar Hierro Avatar answered Nov 19 '22 16:11

Oscar Hierro


As stated by Apple:

If an iOS app is terminated by the system and relaunched, the app can use the same identifier to create a new configuration object and session and retrieve the status of transfers that were in progress at the time of termination. This behavior applies only for normal termination of the app by the system. If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers. In addition, the system does not automatically relaunch apps that were force quit by the user. The user must explicitly relaunch the app before transfers can begin again.

Hope it helps. Stefan

like image 34
blackjacx Avatar answered Nov 19 '22 14:11

blackjacx