Search code examples
iosswiftnsurlsessionurlsession

Prioritisation of networking calls on iOS


I want make use of good prioritisation of networking calls on iOS.

So far, I am using URLSessionTask.priority. I create networking calls like this:

URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data, let response = response {
        // Handle response
    } else {
        // Handle error
    }
}
task.priority = priority

The problem is that I still see that download tasks with priority 0.0 take significant load (up to ~60%) from tasks with priority 1.0, as soon as they start. Sometimes, calls with a priority 1.0 only start when a larger number of low-priority requests completed. Apple's (documentation) confirms that:

To provide hints to a host on how to prioritize URL session tasks from your app, specify a priority for each task. Specifying a priority provides only a hint and does not guarantee performance. [...] There is no API to let you determine the effective priority for a task from a host’s perspective.

I want to implement presumptive downloading and caching, without reducing the performance of user initiated requests. This is especially important on devices with poor connectivity.

Solutions I have considered:

  • Using Alamofire (but afaik they don’t have prioritisation either)
  • Create a custom solution that would only allow n parallel downloads, have a priority queue, and abort/pause very low priority requests when high priority requests come in. To me, though, this sounds like something that must exist already, and also a bit like a fantastic way to shoot myself in the foot, if implemented wrongly.

Alternatives I considered:

  • Only start less important calls after the most important calls are done
  • Don’t do the requests at all on bad connections (follow up question would be how to identify a bad connection)

I am supporting iOS 9 and newer, but would also consider solutions that don't work on iOS 9.


Solution

  • As apple mention in the documentation, the priority field is just a hint, and not really a guarantee of how ressources are going to be spent.

    For more tight enforcement of network priorities; as you mentioned, the only possibility is to limit the number of concurrent requests. This is actually what Alamofire image caching library is doing

    Alamofire does not support priority outside of setting the NSURLSessionTask priority value.