I'm a bit confused about how and when to use beginBackgroundTaskWithExpirationHandler
.
Apple shows in their examples to use it in applicationDidEnterBackground
delegate, to get more time to complete some important task, usually a network transaction.
When looking on my app, it seems like most of my network stuff is important, and when one is started I would like to complete it if the user pressed the home button.
So is it accepted/good practice to wrap every network transaction (and I'm not talking about downloading big chunk of data, it mostly some short xml) with beginBackgroundTaskWithExpirationHandler
to be on the safe side?
I implemented Joel's solution. Here is the complete code:
.h file:
.m file:
Here is a Swift class that encapsulates running a background task:
The simplest way to use it:
If you need to wait for a delegate callback before you end, then use something like this:
The accepted answer is very helpful and should be fine in most cases, however two things bothered me about it:
As a number of people have noted, storing the task identifier as a property means that it can be overwritten if the method is called multiple times, leading to a task that will never be gracefully ended until forced to end by the OS at the time expiration.
This pattern requires a unique property for every call to
beginBackgroundTaskWithExpirationHandler
which seems cumbersome if you have a larger app with lots of network methods.To solve these issues, I wrote a singleton that takes care of all the plumbing and tracks active tasks in a dictionary. No properties needed to keep track of task identifiers. Seems to work well. Usage is simplified to:
Optionally, if you want to provide a completion block that does something beyond ending the task (which is built in) you can call:
Relevant source code available below (singleton stuff excluded for brevity). Comments/feedback welcome.
If you want your network transaction to continue in the background, then you'll need to wrap it in a background task. It's also very important that you call
endBackgroundTask
when you're finished - otherwise the app will be killed after its allotted time has expired.Mine tend look something like this:
I have a
UIBackgroundTaskIdentifier
property for each background taskEquivalent code in Swift
Thank you Ashley Mills, it's work perfectly for me