Dear eskimo
I am working on application (enterprise edition) where i need to download 1,4 gb of corporate files after the installation. All should work in background. It is about 3000+ small files. I tried such approaches:
- downloading small files with help of background NSURLSession. And that gave a lot of issues. As a result i found appropriate explanations from your side here //www.greatytc.com/message/42351#42351 So i decided to switch to zip download.
- achiving all files at the server side and downloading one big zip file. Download goes fine even in background BUT when i get to URLSessionDidFinishEventsForBackgroundURLSession and try to unzip iOs killes the app after 30 sec of execution time. However unzip process takes about 150 seconds on iphone 6 so this solution doesnt work.
- then i tried to ask for an extended background time in beginBackgroundTaskWithExpirationHandler when URLSessionDidFinishEventsForBackgroundURLSession is called and it gave me only 40 seconds. But this is also not enough for unzip process which takes about 150 second.
Would you be so kind to help me with some ideas here? Maybe i should ask for an extended background time later or some other trick?
Usually this will be not enough to finish extraction and app will be terminated here.
You’re missing a key point here. The system doesn’t always terminate your app when you run out of background execution time. Rather it suspends your app. At some point in the future it may terminate your suspended app to reclaim memory, but it may also resume your app, either because the user brought it to the front or for some other background activity. If it does resume your app, for whatever reason, your unzip code will start running again.
Maybe we should inform user before backgroundTimeRemaining will end in order to get him back to the application which will give background CPU time to the application?
The
backgroundTimeRemaining
property is almost never the right solution. If you want to take some sort of remedial action, you should do that in your expiry handler. You should read my
UIApplication Background Task Notes post for more on this.
Is there a way to inform user that data finished loading but not fully extracted due to the limit of background taks?
You can do that via a local notification. One option is to post a local notification for some time in the future, like tomorrow. If you get enough background time to complete the unzip you can cancel the notification. If not, the notification fires and the user can bring the app to the front to complete the job.
One other thing you should consider is incremental extraction. With the approach I outlined above you can run into problems as follows:
Your app stars a download.
Download completes and your app starts an extraction.
Your app runs out of background task time, but it leaves the extraction running in the hope it’ll finished when the app gets resumed.
The system suspends your app.
After some time in the background the system resumes your app.
The system relaunches your app in the background for some other reason (or the user launches your app to the foreground).
The problem here is that any work you get done between steps 2 and 3 is likely to be lost. You can avoid that by doing incremental extraction. That is, when you extract a file within the zip:
Write it to a temporary location.
When it’s done, move it into place.
Make a note on disk that you’ve done that file.
If you die halfway through dealing with the entire archive you can then resume where you left off.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
—
WWDC runs Mon, 4 Jun through to Fri, 8 Jun. During that time all of DTS will be at the conference, helping folks out face-to-face.