My app attempts to upload events and logging data when the user backgrounds the app (i.e., when applicationDidEnterBackground is triggered) by creating an uploadTask using a URLSession with a URLSessionConfiguration.background.
When uploading these events after being backgrounded, we call beginBackgroundTask on UIApplication, which gives us about 25-30 seconds before the expirationHandler gets triggered.
I am noticing, however, that the expirationHandler is frequently called and no upload attempts have even started. This might be reasonable if, for example, I had other uploads in progress initiated prior to backgrounding, but this is not the case.
Could someone confirm that, when initiating an uploadTask while the app is backgrounded using a backgroundSession, there's really no way to predict when that upload is going to begin? My observation is that about 10-20% of the time it does not begin within 20 seconds of backgrounding, and I have many events coming from clients in the field showing as much.
You are mixing two technologies that don’t usually mix. A UIApplication background task makes sense when you’re using a standard session. It prevents the system from suspending your app, giving it time to complete the transfer.
In contrast, when you use a background session you don’t need a UIApplication background task because the transfer gets handed off to a system process that does it on your behalf. That allows the transfer to run even if your app gets suspended. And if your app is suspended when all your session tasks complete, the system will resume (or relaunch) your app in the background to let you know.
There’s a stark latency vs endurance trade-off here:
- Standard sessions are low latency. The transfer starts as soon as you create it [1]. However, the transfer only continues as long as your app can avoid being suspended.
- Background sessions work even if your app gets suspended, but they have high latency. A background session will only start a transfer when conditions are favourable, and the exact definition of favourable is complex. In many cases the background session will delay the transfer until the evening, when the device has access to both Wi-Fi and mains power.
You have to decide how to balance these two. I generally recommend that you use a standard session for small transfers where latency is critical and a background session for large transfers. However, there are other options. For more ramblings about this, see Moving to Fewer, Larger Transfers.
Oh, and if you haven’t already read them, check out UIApplication Background Task Notes and iOS Background Execution Limits.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] Assuming network conditions allow.