Understanding detecting Motion and Orientation with CoreMotion in iOS iOS 23.02.2022

iOS device has a built-in accelerometer that can detect movement and a gyroscope to detect positions. By adding motion and orientation detection, you can create apps that respond to physical gestures as well as touch gestures.

Apple provides a software framework called Core Motion to detect movement beyond simple shakes. With Core Motion you can access the following types of motion data:

  • Acceleration in three dimensions
  • Rotation in three axis

To use Core Motion in an app, you need to import the CoreMotion framework and then create a CMMotionManager object like this

import CoreMotion

let motionManager = CMMotionManager()

Next, you need to check for data updates on a special queue called OperationQueue. You can define this OperationQueue as a constant like this

let motionQueue = OperationQueue()

Detecting acceleration

The accelerometer can measure acceleration and gravity in three-dimensions. The accelerometer can determine not only how an iOS device is being held, but also whether it’s lying face down or face up on a table. Accelerometers measure g-forces, so a value of 1.0 returned by the accelerometer means that 1g is observed in a particular direction.

  • If the device is kept in portrait orientation, it will detect and report about 1g of force exerted on its y-axis.
  • If the device is kept at an angle, that 1g of force will be distributed along different axes depending on how it is being held.

Rapid movement can be detected by looking for accelerometer values considerably larger than 1g. In case you shake, drop, or throw your device, the accelerometer will detect a greater amount of force on one or more axes.

Let's declare necessary variables

import CoreMotion

let motionManager = CMMotionManager() 
let motionQueue = OperationQueue()

You can start accelerometer in onAppear (SwiftUI) or viewWillAppear (UIKit)

motionManager.startAccelerometerUpdates(to: motionQueue) { (data: CMAccelerometerData?, error: Error?) in
    guard let data = data else { 
        print("Error: \(error!)") 
        return 
    }

    let motion: CMAcceleration = data.acceleration 
    motionManager.accelerometerUpdateInterval = 2.5 

    DispatchQueue.main.async {
        print(motion.x)
        print(motion.y)
        print(motion.z)
    } 
}

Connect an iPhone to your Mac through a USB cable and move your iPhone around to see how the different values change.

Detecting rotation

A gyroscope measures orientation and rotation around the x, y, and z-axis.

  • Rotation around the x-axis happens when the iOS device shift backward or forward around its horizontal center.
  • Rotation around the y-axis happens when the iOS device move around its vertical center.
  • Rotation around the z-axis happens when the iOS device rotates clockwise or counter-clockwise

Let's declare necessary variables

import CoreMotion

let motionManager = CMMotionManager() 
let motionQueue = OperationQueue()

You can start accelerometer in onAppear (SwiftUI) or viewWillAppear (UIKit)

motionManager.startAccelerometerUpdates(to: motionQueue) { (data: CMGyroData?, error: Error?) in
    guard let data = data else { 
        print("Error: \(error!)") 
        return 
    }

    let motion: CMRotationRate = data.rotationRate
    motionManager.gyroUpdateInterval = 2.5 

    DispatchQueue.main.async {
        print(motion.x)
        print(motion.y)
        print(motion.z)
    } 
}

Connect an iPhone to your Mac through a USB cable and move your iPhone around to see how the different values change.

Detecting device motion

Detecting device motion data lets you observe roll, pitch, and yaw data.

  • Roll measures the rotation around the vertical axis.
  • Pitch measures the rotation around the horizontal axis.
  • Yaw measures the rotation around an axis that goes through the front and back of an iOS device.

Let's declare necessary variables

import CoreMotion

let motionManager = CMMotionManager() 
let motionQueue = OperationQueue()

You can start accelerometer in onAppear (SwiftUI) or viewWillAppear (UIKit)

motionManager.startDeviceMotionUpdates(to: motionQueue) { (data: CMDeviceMotion?, error: Error?) in
    guard let data = data else { 
        print("Error: \(error!)") 
        return 
    }

    let motion: CMAttitude = data.attitude
    motionManager.deviceMotionUpdateInterval = 2.5 

    DispatchQueue.main.async {
        print(motion.pitch)
        print(motion.yaw)
        print(motion.roll)
    } 
}

Connect an iPhone to your Mac through a USB cable and move your iPhone around to see how the different values change.