What Should I Do When the Normal Processing of My iOS Application is Interrupted?
On an iOS device, various events besides termination can interrupt your app to allow the user to respond and your app moves into the inactive state. If the user chooses to ignore an interruption, your app moves back into the active state and continues running as before. If the user decides to tap the alert, your app then moves into its background state, where it’s suspended but remains in memory.
iOS sends you a number of messages to let you know exactly what’s happening as well as to give you the opportunity to take actions such as save user data and state information, which means saving the point where the user was in the app. Because the app is in the background and still in memory, relaunching is nearly instantaneous.
An app’s objects remain in memory, so they don’t need to be re-created when the app relaunches. If memory becomes constrained, iOS may purge background apps to make more room for the foreground app.
Because these interruptions cause a temporary loss of control by your app, touch events are no longer sent to your app.
The sequence of events always starts the same way — with the applicationWillResignActive: message sent to your app delegate when the app is about to move from active to inactive state. In this method, you should pause ongoing tasks, disable timers, throttle down OpenGL ES frame rates, and generally put things on hold.
What happens after this depends on a) the nature of the interruption, and b) how the user responds to the interruption. Your app may be either moved to the background or reactivated.
If the user responds to the interruption or has launched another app, your app is moved to the background.
The next two bullets explain the messages your app 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 (the current view, options selected, and stuff like that) to a temporary cache file or to the preferences database on disk.
Even though your app 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 app in case it’s subsequently purged from memory.
If your app is purged when it’s in this suspended state, it receives no notice that it’s removed from memory. That’s why you need to save any data when you receive the applicationDidEnterBackground:message.
When your delegate is sent the applicationDidEnterBackground: method, your app has an undocumented amount of time to finish things up. If the applicationDidEnterBackground: 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 app 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 app 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 app 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.
If the user ignores the SMS message, or the app is relaunched from the background, your app is reactivated and starts getting touch and other events.
When your app is reactivated, it’s sent the applicationDidBecomeActive: message.
You can use the applicationDidBecomeActive: method to restore the app 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 app was inactive. If the app was previously in the background, you might need to refresh the user interface.
While an app is in the suspended state, the system tracks and coalesces (really netsout) events that might have an impact on that app when it relaunches. As soon as your app is up and running again, the system delivers those events to it. For most of these events, your app’s existing infrastructure should just respond appropriately.
Apps are generally moved to the background when interrupted. But if the app was compiled with a very early version of the SDK, or is running on an early 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 app supports multitasking, you must still be prepared for your app to be killed without any notification. The user can kill apps explicitly using the multitasking bar. In addition, if memory becomes constrained, the system might remove apps from memory to make more room. If it does remove your suspended app, it doesn’t give you any warning!
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 app won’t be returning from the background.
Your applicationWillTerminate: method implementation has a limited amount of time to do what it needs to do and return. Any longer than that and your app is terminated and purged from memory.