How Interruptions Are Handled in iOS - dummies

By Neal Goldstein, Dave Wilson

If the user responds to the interruption (the SMS message for example) or has launched another application, your application is moved to the background.

The iOS application life cycle.
The iOS application life cycle.

When the user accepts the notification or interruption, or presses the Home button (or when the system launches another application), your application moves into the background state, where it’s suspended. (If an app needs to continue running, it can request execution time from the system.)

Here are the messages your application can respond to after it’s been moved into the background:

  • The applicationDidEnterBackground: message: When your app first enters the background state, it’s sent the applicationDidEnterBackground: message. In this method, you should save any unsaved data or state (where the user is in the app — the current view, options selected, and stuff like that) to a temporary cache file or to the preferences database “on disk.”

    Know that Apple calls the iOS storage system a disk even though it is a solid-state drive, so if Apple calls it that, you probably should too, just so you don’t confuse too many people.

    Even though your application enters the background state, you have no guarantee that it will remain there indefinitely. If memory becomes constrained, iOS will purge background apps to make more room for the foreground app.

    You need to do everything necessary to be able to restore your application in case it’s subsequently purged from memory so that the next time the user launches your app, your application can use that information to restore your app to its previous state. You also have to do additional cleanup operations, such as deleting temporary files.

    If your application is purged when it’s in this suspended state, it receives no notice that it’s removed from memory. You need to save any data beforehand!

    When your delegate is sent the applicationDidEnterBackground: method, your app has an undocumented amount of time to finish things up. If the method doesn’t return before time runs out (or if your app doesn’t request more execution time from iOS), your app is terminated and purged from memory.

    If your application requests more execution time or it has declared that it does background execution, it’s allowed to continue running after the applicationDidEnterBackground: method returns. If not, your (now) background application is moved to the suspended state shortly after returning from the applicationDidEnterBackground: method.

    If the application is in the background, it then may be relaunched. This can happen if the user selects the app from the Home screen or the multitasking bar, or it’s launched by the system if the app processes events in the background or monitors a significant location change, for example.

  • The applicationWillEnterForeground: message: When your application is relaunched from the background, it’s sent the applicationWillEnterForeground: message. In this method, you need to undo what you did in the applicationDidEnterBackground: method (not applicationWillResignActive; you undo that next).

If the user ignores the SMS message, or the app is relaunched from the background, your application is reactivated and starts getting touch and other events.

When your application is reactivated, it’s sent the applicationDidBecomeActive: message.

You can use the applicationDidBecomeActive: method to restore the application to the state it was in before the interruption. Here you undo what you did in the applicationWillResignActive method, such as restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, you might need to refresh the user interface.

While an application is in the suspended state, the system tracks and coalesces (really nets out) events that might have an impact on that application when it relaunches. As soon as your application is up and running again, the system delivers those events to it.

For most of these events, your application’s existing infrastructure should just respond appropriately. For example, if the device orientation changed, your application’s view controllers would automatically update the interface orientation in an appropriate way.

Apps are generally moved to the background when interrupted or when the user quits. But if the app was compiled with an earlier version of the SDK, or is running on an earlier version of the operating system that doesn’t support multitasking — or if you decide that you don’t want your app to run in the background and you set the UIApplicationExitsOnSuspend key in its Info.plist file — iOS terminates your app.

Even if your application supports multitasking (almost all do at this point), you must still be prepared for your application to be killed without any notification. The user can kill applications explicitly using the multitasking bar.

In addition, if memory becomes constrained, the system might remove applications from memory to make more room. If it does remove your suspended application, it doesn’t give you any warning, much less notice! However, if your application is currently running in the background state, the system does call the applicationWillTerminate: method of the application delegate.

When your application delegate is sent the applicationWillTerminate: message in nonmultitasking applications, or those running in the background, you need to do the same kinds of things you do in applicationDidEnterBackground:, except this time you do them knowing that your application won’t be returning from the background.

Your applicationWillTerminate: method implementation has a limited (albeit undocumented) amount of time to do what it needs to do and return. Any longer than that and your application is terminated and purged from memory. (The Terminator doesn’t kid around.)