title: Networking search + image downloads operations in OperationQueue: Operations vs URLSession's delegateQueue
body: <p>I need to perform this scenario: </p>
  
  <ul>
  <li>User provides some search parameters which I should use to call an URL and parse its response (I use an <code>URLSessionDataTask</code> for this).</li>
  <li>That response is a JSON that may contain several image URL's I should then call to download (I use as many <code>URLSessionDownloadTask</code> as images URL's I got), and then show them in an <code>UITableView</code> (one image per cell).</li>
  <li>User should be able to cancel the current search to start a new one, so previous complete search + downloads process could be still in progress at that moment.</li>
  </ul>
  
  <p>Moreover, for the data task (initial search) I use an <code>URLSessionConfiguration.default</code>, and for the several download tasks I use <code>URLSessionConfiguration.background</code>.</p>
  
  <p>Initial search (data task) and the set N image downloads (N download tasks) are serial, meaning that I need to get the response of the initial search to start the image downloads. But I need the N image downloads to be concurrent, since I am going to show each image in its corresponding cell once that certain image has finished being downloaded.</p>
  
  <p>On the other hand, all these networking operations (search + downloads) need to be asynchronous, of course.</p>
  
  <p>My question: I have seen that <code>URLSession</code> has an initializer that can be provided an <code>OperationQueue</code> as <code>delegateQueue</code> parameter. Regarding this option, I think I should do something like this:</p>
  
  <pre><code>self.queue = OperationQueue()
  self.queue.qualityOfService = .userInitiated
  self.defaultSession = URLSession(configuration: configuration, delegate: nil, delegateQueue: queue)
  self.backgroundSession = URLSession(configuration: backgroundConfiguration, delegate: self, delegateQueue: queue)
  </code></pre>
  
  <p>Then I should be able to call <code>self.queue.cancelAllOperations()</code> when user starts a new search.</p>
  
  <p>Would this be the correct approach to my scenario? Would the images be downloaded concurrently?</p>
  
  <p>The other option I have thought about is to create that same <code>OperationQueue</code> but, instead of passing it as <code>delegateQueue</code> to both <code>URLSession</code>, to model the data task and the download tasks as <code>Operation</code> and call <code>self.queue.addOperation</code>.</p>
  
  <p>Is there any difference in behaviour and performance between this two options? Which one should be the appropriate for my scenario? Or would it be better a different approach (in such case, which one)?</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Other option I'm thinking of is: each cell to have a reference to its own <code>URLSessionDownloadTask</code> and call to download its image when cell is reused, but cancelling the task when a new download is going to be performed, something like that:</p>
  
  <pre><code>var downloadTask: URLSessionDownloadTask?
  
  func downloadImage(imageUrl: URL) {
      downloadTask?.cancel()
  
      let request = URLRequest(url: url)
      downloadTask = backgroundSession.downloadTask(with: request)
      downloadTask?.resume()
  }
  </code></pre>
  
  <p>Here I don't use the operation queue, just cancel the task. Is this correct and better option? Should I then call <code>downladTask?.cancel()</code> when the cell is dequeued?</p>