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.