1

We have a common Requesthandler.swift file which handles get, post http methods. We are using this file accross the App to have http request. What should be the value for the delegateQueue, when we initialising the URLSession.

let session = URLSession(configuration: config, delegate: self, delegateQueue:OperationQueue.main)
Rob
  • 415,655
  • 72
  • 787
  • 1,044
Shamil
  • 727
  • 1
  • 9
  • 17

2 Answers2

2

The key consideration is that the queue should be a serial queue. As the docs say:

The queue should be a serial queue, in order to ensure the correct ordering of callbacks.

So, if you instantiate your own OperationQueue, make sure to set its maxConcurrentOperationCount to 1.

The docs go on to say:

If [the delegate queue is] nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.

As such, we generally we would just leave this as nil, and let URLSession take care of this for us.

One generally would not use the main queue, though. This is largely a matter of convention (as URLSession.shared, which we generally use if we don’t need delegate methods or custom behaviors, uses a serial background queue). This practice, of using a serial background queue, is advisable, as you a lower the risk that some slow parsing operation (or whatever) in a delegate method or completion handler would ever affect your main thread responsiveness. That having been said, whenever using a serial background queue, make sure to dispatch UI updates (and the like) back to the main queue.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • "If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls." Will this serial queue runs in main thread or not? – Shamil Jan 07 '21 at 04:04
  • 1
    When you (or `URLSession`) create a queue, it's generally not running on the main thread. So, use `nil`, let `URLSession` instantiate a serial background queue, and then if you have something that must run on the main thread (e.g. UI updates or the like), then manually dispatch that back to the main queue yourself. – Rob Jan 07 '21 at 04:58
  • If you are setting as nil. Will it be background or main. i mean by default – Shamil Jan 07 '21 at 06:56
  • If you supply `nil`, it will create a background serial queue. This is not the main queue. – Rob Jan 07 '21 at 07:05
  • Thanks @Rob. As we know background Queue or Thread is not same as When App in background. If api is ongoing, if all of sudden if App goes background the entire api will be dead. how to handle this scenerio? – Shamil Jan 07 '21 at 07:27
  • You have two options. If you just need a little time (less than 30 seconds) to complete a request, you can [request a little more time](https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/extending_your_app_s_background_execution_time). This is simplest approach. If however, you’re downloading large files and need more than 30 seconds, see [Downloading Files in the Background](https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_in_the_background). – Rob Jan 07 '21 at 15:18
  • By the way, do not conflate the “background” thread/queue (as opposed to the main queue) with the “background” app state (as opposed to running in the foreground or being suspended) with the “background” `URLSession` configuration (handing the network request out of process, to some OS daemon). Those are three completely unrelated uses of the term “background”. Each has nothing to do with the others. – Rob Jan 07 '21 at 16:29
  • Surprisingly, Apple engineer recently advised me to use `main` queue for this. Here's a [cogent explanation](https://inessential.com/2021/01/27/urlsession_delegate_main_queue) of this. – vortek May 03 '23 at 16:19
  • The main thread obviously *can* be used (it won’t block the main thread), but I still wouldn’t advise it. I would describe it as a convenient, but imprudent, anti-pattern. You now you really have to be extremely careful what you do on that queue. Developers working in that codebase would never reasonably guess that you had used the main queue, and could easily introduce code that made the UI stutter and would take them a long time to find the source of the problem. It just violates such a well established convention, that it becomes more problematic than helpful, IMHO. – Rob May 03 '23 at 16:51
0

If you use it across the app for all http that is the correct way to do it. However, I would suggest not to create your own session. There is already something exactly for that, which is URLSession.shared, albeit with (just a few) limitations as discussed in the docs.

If you can live with the limitations great - use the shared session; otherwise use nil as Rob suggested or if you DIY the queue then you do NOT want to use main as your delegate queue. You definitely want a background queue here. If you DIY then you'd probably create a singleton queue and use that for all requests and configure it according to taste (and make it serial - see Rob's answer).

Finally, since the delegate will call the completion on the delegate queue, which is NOT main, you should switch to main in the completion whenever you need to update UI, so there will probably be a lot of switching to main there. That is not wrong nor telling you to use main as queue.

skaak
  • 2,988
  • 1
  • 8
  • 16
  • "If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls." Will this serial queue runs in main thread or not? – Shamil Jan 07 '21 at 04:05
  • @Shamil I see you have an answer to this. Note again what I suggest. I think what you do by doing all http in a single place is correct. Then, if possible, use the shared session e.g. ```[NSURLSession.sharedSession downloadTaskWithURL:remoteUrl completionHandler:...``` or ```[NSURLSession.sharedSession dataTaskWithURL:remoteUrl completionHandler:...```. – skaak Jan 07 '21 at 08:30
  • PS : based on some of the other comments. This https://stackoverflow.com/questions/20604910/what-is-difference-between-nsurlsessiondatatask-vs-nsurlsessiondownloadtask also discusses the difference between data and download task. – skaak Jan 10 '21 at 09:07