Guides and Sample Code

Developer

Energy Efficiency Guide for iOS Apps

On This Page

Reduce the Frequency of Motion Updates

Users generate motion events whenever they move, shake, or tilt an iOS device. These motion events are detected by device hardware, such as the accelerometer, gyroscope, and magnetometer. An app can use this information to provide an immersive user experience. For example, a game may allow the user to move a character around the screen by tilting the device.

Stop Orientation Change Notifications When No Longer Needed

Your app can register to receive notifications when the orientation of the device changes, providing an opportunity to readjust the layout or perform other reactive actions. Make sure you disable these notifications if they become unnecessary—for example, if the user has navigated to a different view that is only available in portrait orientation. Doing so lets the system power down the accelerometer hardware if it’s not being used elsewhere.

Before registering for orientation change notifications, activate the accelerometer by calling the beginGeneratingDeviceOrientationNotifications method for the current device object. To start notifications, send the message addObserver:selector:name:object: to the default notification center of your app (an instance of NSNotificationCenter). Pass it UIDeviceOrientationDidChangeNotification and a selector to call when the device orientation changes. Then, when you no longer need to know about orientation changes, call the default notification center’s removeObserver: method to stop the notifications. Finally, call the endGeneratingDeviceOrientationNotifications method for the current device object to let the system know you don’t need the accelerometer anymore. See Listing 15-1.

Listing 15-1Starting and stopping orientation change notifications when a view appears and dismisses

Objective-C

  1. -(void) viewDidLoad {
  2. // Turn on the accelerometer
  3. [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  4. //Register for orientation change notifications
  5. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
  6. }
  7. - (void)orientationChanged:(NSNotification *)notification {
  8. // Respond to changes in orientation here
  9. }
  10. -(void) viewDidDisappear: (BOOL) animated {
  11. // Stop receiving orientation change notifications
  12. [[NSNotificationCenter defaultCenter] removeObserver:self];
  13. // Turn off the accelerometer
  14. [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
  15. }

Swift

  1. override func viewDidLoad() {
  2. // Turn on the accelerometer
  3. UIDevice.currentDevice.beginGeneratingDeviceOrientationNotifications()
  4. //Register for orientation change notifications
  5. NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationChanged:", name: UIDeviceOrientationDidChangeNotification, object: nil)
  6. }
  7. func orientationChanged(notification: NSNotification!) {
  8. // Respond to changes in orientation here
  9. }
  10. override func viewDidDisappear(animated: Bool) {
  11. // Stop receiving orientation change notifications
  12. NSNotificationCenter.defaultCenter().removeObserver(self)
  13. // Turn off the accelerometer
  14. UIDevice.currentDevice().endGeneratingDeviceOrientationNotifications()
  15. }

Request Fewer Continuous Motion Updates

The Core Motion framework provides APIs that let an app receive continuous motion updates in the form of accelerometer, gyroscope, and device motion (rotation, acceleration, and more) events. Once any of these APIs is initiated, the app can request motion updates at any time. It can also register to receive recurring updates.

Before registering for recurring updates, specify an interval that meets your app’s needs. The larger the interval, the fewer events are delivered to your app, improving battery life. Call any of the methods in Table 15-1 on the Core Motion Manager class (CMMotionManager), and pass an interval of type NSTimeInterval.

Table 15-1Core Location Manager methods for specifying a recurring motion update interval

Method

Description

accelerometerUpdateInterval

Call this method to set the interval for recurring accelerometer updates.

gyroUpdateInterval

Call this method to set the interval for recurring gyroscope updates.

deviceMotionUpdateInterval

Call this method to set the interval for recurring device motion updates.

To enable continuous motion tracking, call any of the methods in Table 15-2 on the CMMotionManager class, depending on the requirements of your app.

Table 15-2Core Location Manager methods for enabling continuous motion tracking

Method

Description

startAccelerometerUpdates

Call this method to start recording accelerometer events. To request event details at any time, query the accelerometerData property of the CMMotionManager class.

startAccelerometerUpdatesToQueue:withHandler:

Call this method to start recording accelerometer events and receiving updates. Pass it a processing handler to call at a recurring interval, and an operation queue on which to run the handler.

startGyroUpdates

Call this method to start recording gyroscope events. To request event details at any time, check the gyroData property of the CMMotionManager class.

startGyroUpdatesToQueue:withHandler:

Call this method to start recording gyroscope events and receiving updates. Pass it a handler to call at a recurring interval, and an operation queue on which to run the handler.

startDeviceMotionUpdates

Call this method to start recording device motion events. To request event details at any time, check the deviceMotion property of the CMMotionManager class.

startDeviceMotionUpdatesToQueue:withHandler:

Call this method to start recording device motion events and receiving updates. Pass it a handler to call at a recurring interval, and an operation queue on which to run the handler.

When motion updates are no longer needed, make sure you explicitly stop the updates so the corresponding hardware can be powered down. Call any of the methods in Table 15-3 on the CMMotionManager class, as appropriate.

Table 15-3Core Location Manager methods for stopping continuous motion tracking

Method

Description

stopAccelerometerUpdates

Call this method to stop receiving accelerometer updates.

stopGyroUpdates

Call this method to stop receiving gyroscope updates.

stopDeviceMotionUpdates

Call this method to stop receiving device motion updates.

Listing 15-2 demonstrates the techniques above by registering for and stopping recurring accelerometer updates.

Listing 15-2Registering for and stopping recurring accelerometer motion updates

Objective-C

  1. -(void) viewDidLoad {
  2. [super viewDidLoad];
  3. // Create a Core Motion Manager object
  4. self.motionManager = [[CMMotionManager alloc] init];
  5. }
  6. - (void)startAccelerometerUpdates {
  7. // Check whether the accelerometer is available
  8. if ([self.motionManager isAccelerometerAvailable] == YES) {
  9. // Update the recurring update interval
  10. [self.motionManager setAccelerometerUpdateInterval:updateInterval];
  11. // Start accelerometer updates
  12. [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
  13. // Handler to process accelerometer data
  14. }];
  15. }
  16. }
  17. - (void)stopUpdates {
  18. // Check whether the accelerometer is available
  19. if ([self.motionManager isAccelerometerActive] == YES) {
  20. // Start accelerometer updates
  21. [self.motionManager stopAccelerometerUpdates];
  22. }
  23. }

Swift

  1. override func viewDidLoad() {
  2. // Create a location manager object
  3. self.motionManager = CMMotionManager()
  4. }
  5. func startAccelerometerUpdates() {
  6. // Check whether the accelerometer is available
  7. if self.motionManager.accelerometerAvailable {
  8. // Update the recurring update interval
  9. self.motionManager.accelerometerUpdateInterval = updateInterval
  10. // Start accelerometer updates
  11. self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) { (accelerometerData: CMAccelerometerData!, error: NSError!) in
  12. // Handler to process accelerometer data
  13. }
  14. }
  15. }
  16. func stopUpdates() {
  17. // Check whether the accelerometer is available
  18. if self.motionManager.accelerometerActive {
  19. // Start accelerometer updates
  20. self.motionManager.stopAccelerometerUpdates()
  21. }
  22. }