iOS 4 bought a host of new features and APIs. One of the most exciting for me was the ability to initiate long running tasks that have the ability to continue execution even after your application has moved into the background, that is once it is no longer running in the foreground.
The primary methods used to trigger this functionality are:
Both methods are available on instances of UIApplication. Apple’s documentation for beginBackgroundTaskWithExpirationHandler: states:
Each call to this method must be balanced by a matching call to the endBackgroundTask: method.
These rules for background tasks are analogous to memory management rules within Objective-C, where it is crucial to balance retain and release calls. In either case the consequences are severe if you don’t get it right. For example if you do not call endBackgroundTask: for each task before its’ time expires, the system terminates the app.
If you do not call endBackgroundTask: for each task before time expires, the system terminates the application.
The exact amount of time your app is given is undefined. However, using the backgroundTimeRemaining method on UIApplication, your app can determine how much time is remaining at any point during execution.
The simplest use case may involve only one background task. However, depending upon your app’s requirements and/or complexity you may have many background tasks potentially being managed across disparate areas of your app.
If you’re working with background tasks I recommend you pay special attention to keeping the begin and end calls balanced. One useful strategy is to set a symbolic breakpoint on the UIApplicationEndBackgroundTaskError function. This function is called when your app calls the endBackgroundTask: method with a backgroundTaskIdentifier that has already been ended or does not exist. You may also place a breakpoint within the expiration handler block that you pass into the beginBackgroundTaskWithExpirationHandler: method.
These two breakpoints should allow you to catch any unexpected scenarios where you haven’t correctly balanced the two method calls. Just be sure to execute your app with breakpoints on during development!