My NSURLSessionDelegate methods do not receive a call during background loading

I am trying to configure the boot using NSURLSession , which will continue in the background. I have a singleton class called DownloadManager that creates an NSURLSession and runs the download task as follows:

 - (id)init { self = [super init]; if (self) { self.queue = [[NSOperationQueue alloc] init]; self.queue.maxConcurrentOperationCount = 1; // Initialize the background session. self.session = [self backgroundSession]; } return self; } - (NSURLSession *)backgroundSession { static NSURLSession *session = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.mycompany.myapp.BackgroundSession"]; session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:self.queue]; }); return session; } - (void)startDownload:(Download *)download { NSURL *remoteURL = ... NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:remoteURL]; [task resume]; } 

I implemented the NSURLSessionDelegate and NSURLSessionDownloadDelegate , including URLSessionDidFinishEventsForBackgroundURLSession: In addition, my application delegate implements application:handleEventsForBackgroundURLSession:completionHandler:

However, when I move my application to the background by pressing the home button after starting the download, all delegate methods loaded stop shooting, and application:handleEventsForBackgroundURLSession:completionHandler: never called. Downloading continues, and if I wait long enough to finish, then URLSession:downloadTask:didFinishDownloadingToURL: is the moment when I bring my application back to the forefront. This means that I can not do post-processing in the background (for example, save kernel data, start a new boot, etc.).

I tried adding the "Background fetch" background to my plist in case it was necessary, and I tried changing my identifier used to create the NSURLSessionConfiguration background configuration as suggested in this answer . Did I make a mistake in configuring this, or should I not handle sending delegate events in the background?

+8
ios objective-c cocoa-touch ios7 nsurlsession
source share
1 answer

You will not see delegate events loaded, triggered when individual downloads end in the background, but rather only after restarting the application. for example, when all downloads are completed successfully (when handleEventsForBackgroundURLSession is called) or when you manually restart the application.

As for why you do not see handleEventsForBackgroundURLSession , I can only think about the possibilities of the pair (though unlikely):

  • Make sure that the signature handleEventsForBackgroundURLSession in your application is absolutely correct (capitalization, spelling, etc.). A small typo will not trigger a warning, but it will cause it to not be triggered. Therefore, it should be:

     - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler { // save the completionHandler here } 
  • Are you sure all your background downloads are ending? If for some reason one of them freezes or crashes, this will prevent the background session from starting and because the delegate method is called only when everything is done, this means that your application will not be activated. I recommend that you carefully verify that all downloads are complete.

  • Have you checked the device console? (This can be seen if you go to the "Devices" section of the Xcode "Organizer".) Sometimes interesting diagnostic messages appear that the background daemon will record. Check it out if you haven't already. There are many interesting things.

  • If you manually kill the application using SpringBoard (double-click on the physical home button, hold the application icon until it clicks, click on the red "x"), which will kill the background loading tasks, and therefore you won. Do not receive notification that all downloads are done. . Make sure you implement URLSession:task:didCompleteWithError: so you can see this error (and any others).

    If, however, I programmatically crash the application, as shown in the WWDC 2013 What's New video in Foundation Networking , or if it is completed by the system, then the initial download will end correctly and the delegation method of the application will be called correctly.

Only a few ideas to consider.

+8
source share

All Articles