Prioritisation of networking calls on iOS

Viewed 1459

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.

0 Answers
Related