Search code examples

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?


  • 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) {