title: NSURLSession Threads: Tracking multiple background downloads
body: <p>So I'm creating my download on the main thread</p>
  
  <pre><code>NSURLRequest *request = [NSURLRequest requestWithURL:download.URL];
  NSURLSessionDownloadTask *downloadTask = [self.downloadSession downloadTaskWithRequest:request];
  [downloadTask resume];
  </code></pre>
  
  <p>and adding the NSManagedContextID associated with the download to an NSMutableDictionary, 
  so I can retrieve it later in the delegate call-backs</p>
  
  <pre><code>[self.downloads setObject:[download objectID] forKey:[NSNumber numberWithInteger:downloadTask.taskIdentifier]];
  </code></pre>
  
  <p>My <code>self.downloadSession</code> above is configured like this</p>
  
  <pre><code>- (NSURLSession *)backgroundSession
  {
  static NSURLSession *session = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&amp;onceToken, ^{
      NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.test.backgroundSession"];
      configuration.discretionary = YES;
      session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
  });
  return session;
  }
  </code></pre>
  
  <p>My problem is the delegate callbacks seem to be called on different threads</p>
  
  <pre><code>- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
  {   
      NSManagedObjectID *downloadID = [self.downloads objectForKey:[NSNumber numberWithInteger:downloadTask.taskIdentifier]];
  
      double progress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
  
      NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:downloadID,@"download",[NSNumber numberWithDouble:progress],@"progress", nil];
  
      [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadProgress" object:nil userInfo:userInfo];
  
  } 
  </code></pre>
  
  <p>So when I access self.downloads to get the correct objectID, I'm actually accessing the NSMutableDictionary from a different thread than the one it was created on, and I believe NSMutableDictionary isn't thread safe. So what is the best solution for this, I could used something like this</p>
  
  <pre><code>session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
  </code></pre>
  
  <p>when declaring the session, set the delegate queue to the mainQueue which causes all the delegates to be called on the main thread, but I would like to keep all the callbacks on a background thread if possible</p>