Reputation: 2968
I followed this tutorial Downloading files in background with URLSessionDownloadTask
And this Apple doc Downloading Files in the Background
I tried to setup because we have a long running API
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background")
config.timeoutIntervalForRequest = 120
config.timeoutIntervalForResource = 180
But I bumped into this weird issue:
If the server does not response with any piece of data, meaning that
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
does not get called at all.
The app will kill off previous request and retry a new request every 66 seconds. I don't know where this number come from but from my experiment, it's roughly 66 seconds
If I set the timeoutIntervalForRequest = 10
the sure enough, the app will retry the request every 10 seconds but any attempt to set it above 66 seconds doesn't work
Not sure if anyone encounter the same issue and found a solution.
Just 1 note: the whole thing will timeout when it reach 180 seconds and the app stop retrying new requests
Upvotes: 3
Views: 767
Reputation: 10417
First, that's a bug. Please file it at bugreport.apple.com. The timeout should not be ignored like that. Of course, there's a decent chance that this is a power management issue and won't be fixed, so I wouldn't hold your breath.
Second, you're approaching the problem in a way that is pretty much guaranteed to cause problems even if the timeout bug were fixed. The fact that your server isn't sending back any bytes to keep the connection alive is, of course, the reason the iOS device is disconnecting, but even if you change that and make it send out a bogus header one byte at a time every five seconds until the data is ready, you'll still have problems.
Basically, on a mobile device, you really shouldn't keep a long-running connection open to a remote server for any reason. It massively wastes battery to keep the Wi-Fi radio on continuously, much less the cellular radio, and worse, that connection could fail at any time when the user walks out of range, switches cell sites, or otherwise momentarily loses connectivity. Networks are crap — cellular networks doubly so.
A much better approach for long-running server processing is to do it asynchronously:
This approach avoids keeping the radio hot except for a couple of seconds on either side of your polling requests, and it makes the timeout issue entirely moot.
Upvotes: 1