Ios – Proper use of beginBackgroundTaskWithExpirationHandler


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?

Best Solution

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:

- (void) doUpdate 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [self beginBackgroundUpdateTask];

        NSURLResponse * response = nil;
        NSError  * error = nil;
        NSData * responseData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];

        // Do something with the result

        [self endBackgroundUpdateTask];
- (void) beginBackgroundUpdateTask
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgroundUpdateTask];

- (void) endBackgroundUpdateTask
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;

I have a UIBackgroundTaskIdentifier property for each background task

Equivalent code in Swift

func doUpdate () {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

        let taskID = beginBackgroundUpdateTask()

        var response: URLResponse?, error: NSError?, request: NSURLRequest?

        let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)

        // Do something with the result



func beginBackgroundUpdateTask() -> UIBackgroundTaskIdentifier {
    return UIApplication.shared.beginBackgroundTask(expirationHandler: ({}))

func endBackgroundUpdateTask(taskID: UIBackgroundTaskIdentifier) {
Related Question