Search code examples
objective-cnsurlsessionnsurlsessiondownloadtask

URLSession Download Task delegate only called after all tasks finish


I have an NSURLSession with a background configuration downloading two or three files simultaneously. Everything seems to be working fine except that the delegate methods

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 
didFinishDownloadingToURL:(NSURL *)location

and

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
didCompleteWithError:(NSError *)error

are only called when all of the download tasks complete, not individually as each one completes. Other delegate methods for updating the download progress function individually as they should.

The problem also doesn't occur when I set the NSURLSessionConfiguration to defaultConfiguration, but then background downloads obviously won't work. Am I missing something? Am I supposed to have separate NSURLSessions for each download task?

EDIT: as requested, here is the code for creating the session and configuration. I've included both the default configuration and the background session configuration, although only one is used in the creation.

  if (!_backgroundURLSession) {
    NSString *sessionID = [NSString stringWithFormat:@"%@.BackgroundSession", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]];


    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID];
    NSURLSessionConfiguration *defaultConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    _backgroundURLSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
  }

For starting any download, [_backgroundURLSession downloadTaskWithURL:[NSURL URLWithString:_url]] is used to create a NSURLSessionDownloadTask, the download task is stored in a NSMutableDictionary with the URL as the key. The download task is removed from the dictionary in the delegate method when the task completes. The dictionary is used mainly to keep track of progress and to cancel tasks.


Solution

  • It seems this behavior was specific to the iOS Simulator, along with a few other weird behaviors in NSURLSession. When I ran the code on a device, everything worked as it should.