Work Less in the Background
When the user isn’t actively using your app, the system places it into a background state. The system may eventually suspend your app if it’s not performing important work, such as finishing a task the user initiated or running in a specially declared background execution mode.
You can use Energy organizer to view crash and energy reports that are generated from log information collected automatically from TestFlight users and with permission from users of the App Store versions of your apps. To learn more, see Energy organizer.
Common Causes of Energy Wasted by Background Apps
Apps performing unnecessary background activity waste energy. The following are some common causes of wasted energy in background apps:
Not notifying the system when background activity is complete
Playing silent audio
Performing location updates
Interacting with Bluetooth accessories
Downloads that could be deferred
Suspend Activity When Your App Becomes Inactive or Moves to the Background
Implement UIApplicationDelegate
methods in your app delegate to receive calls and suspend activity when your app becomes inactive or transitions from the foreground to the background.
applicationWillResignActive
The applicationWillResignActive:
method is called when your app enters an inactive state, such as when a phone call or text message comes in, or the user switches to another app and your app begins transitioning to a background state. This is a good place to pause activity, save data, and prepare for possible suspension. See Listing 3-1.
Objective-C
- (void)applicationWillResignActive:(UIApplication *)application {
// Halt operations, animations, and UI updates
}
Swift
optional func applicationWillResignActive(_ application: UIApplication) {
// Halt operations, animations, and UI updates
})
applicationDidEnterBackground
The applicationDidEnterBackground:
method is called immediately after your app enters a background state. Stop any operations, animations, and UI updates immediately. See Listing 3-2.
Objective-C
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Halt operations, animations, and UI updates immediately
}
Swift
optional func applicationDidEnterBackground(_ application: UIApplication) {
// Halt operations, animations, and UI updates immediately
})
iOS allows only a few seconds for the applicationDidEnterBackground
method to run. If your app needs more time to finish performing essential user initiated tasks, it should request more background execution time—the system allows up to a few more minutes of time on request. Call the beginBackgroundTaskWithExpirationHandler:
method and pass it a handler, to be called if the extra time runs out. Next, run the remaining tasks on a dispatch queue or secondary thread.
When background tasks are done, call the endBackgroundTask:
method to let the system know processing is complete. If you don’t call this method and background execution time exhausts, then the completion handler is called to give you one last shot at wrapping things up. After that, your app is suspended. See Listing 3-3.
Objective-C
// Request additional background execution time
UIBackgroundTaskIdentifier bgTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
// Completion handler to be performed if time runs out
}];
// Initiate background tasks
// Notify the system when the background tasks are done
[[UIApplication sharedApplication] endBackgroundTask:bgTaskID];
Swift
// Request additional background execution time
var bgTaskID: UIBackgroundTaskIdentifier = 0
bgTaskID = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler() {
// Completion handler to be performed if time runs out
}
// Initiate background tasks
// Notify the system when the background tasks are done
UIApplication.sharedApplication().endBackgroundTask(bgTaskID)
Resume Activity When Your App Becomes Active
Implement UIApplicationDelegate
methods in your app delegate to receive calls and resume activity when your app becomes active again.
applicationWillEnterForeground
The applicationWillEnterForeground:
method is called immediately before your app transitions from a background app to the active app. Start resuming operations, loading data, reinitializing the UI, and getting your app ready for the user. See Listing 3-4.
Objective-C
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Prepare to resume operations, animations, and UI updates
}
Swift
optional func applicationWillEnterForeground(_ application: UIApplication) {
// Prepare to resume operations, animations, and UI updates
})
applicationDidBecomeActive
The applicationDidBecomeActive:
method is called immediately after your app becomes the active app, after being launched by the system or transitioning from a background or inactive state. Fully resume any operations that were halted. See Listing 3-5.
Objective-C
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Resume operations, animations, and UI updates
}
Swift
optional func applicationDidBecomeActive(_ application: UIApplication) {
// Resume operations, animations, and UI updates
})
Resolving Runaway Background App Crashes
iOS employs a CPU Monitor that watches background apps for excessive CPU usage and terminates them if they fall outside of certain limits. Most apps performing normal background activity should never encounter this situation. However, if your app reaches the limits and is terminated, the crash log indicates the reason for the termination. An exception type of EXC_RESOURCE
and subtype of CPU_FATAL
is specified, along with a message indicating that limits were exceeded. See Listing 3-6.
Exception Type: EXC_RESOURCE
Exception Subtype: CPU_FATAL
Exception Message: (Limit 80%) Observed 89% over 60 seconds
The log also includes a stack trace, which lets you determine what your app was doing right before it was terminated. By analyzing the stack trace, you can identify the location of the runaway code and resolve it.
Copyright © 2018 Apple Inc. All rights reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13