iOS devices like iPhones and iPads come with built-in motion sensors capable of detecting changes in acceleration, rotation, and magnetic field. This post presents examples for reading accelerometer, gyroscope, and magnetometer data using CMMotionManager in Swift:

  1. iOS Accelerometer Example
    a. CMAccelerometerData and Acceleration
  2. iOS Gyroscope Example
    b. CMGyroData and Rotation
  3. iOS Magnetometer Example
    c. CMMagnetometerData and Magnetic Field
  4. CMMotionManager Real-Time Updates Example
    d. CMDeviceMotion
    e. CMDeviceMotion Roll, Pitch, and Yaw
    f. CMDeviceMotion Gravity

Useful note: according to Apple's documentation, the maximum update frequency of motion sensor updates is "hardware dependent but is usually at least 100 Hz".

iOS Accelerometer Example

The accelerometer sensor reads device acceleration. To read accelerometer data first create a CMMotionManager instance. Then, use the accelerometerData property to read the most recent accelerometer value or the startAccelerometerUpdates(to:) method to start accelerometer updates:

// Create a CMMotionManager instance
let manager = CMMotionManager()

// Read the most recent accelerometer value
manager.accelerometerData?.acceleration.x
manager.accelerometerData?.acceleration.y
manager.accelerometerData?.acceleration.z

// How frequently to read accelerometer updates, in seconds
manager.accelerometerUpdateInterval = 0.1

// Start accelerometer updates on a specific thread
manager.startAccelerometerUpdates(to: .main) { (data, error) in
    // Handle acceleration update
}

CMAccelerometerData and Acceleration

The accelerometerData variable on a CMMotionManager is a CMAccelerometerData class. CMAccelerometerData also contains a timestamp, in addition to acceleration:

// Time the accelerometer reading was taken
accelerometerData.timestamp

// Device acceleration values
accelerometerData.acceleration.x
accelerometerData.acceleration.y
accelerometerData.acceleration.z

iOS Gyroscope Example

The gyroscope sensor reads device rotation. To read gyroscope data first create a CMMotionManager instance. Then, use the gyroData property to read the most recent gyroscope value or the startGyroUpdates(to:) method to start gyroscope updates:

// Create a CMMotionManager instance
let manager = CMMotionManager()

// Read the most recent gyroscope value
manager.gyroData?.rotationRate.x
manager.gyroData?.rotationRate.y
manager.gyroData?.rotationRate.z

// How frequently to read gyroscope updates,
// in seconds
manager.gyroUpdateInterval = 0.1

// Start receiving gyroscope updates
// on a specific thread
manager.startGyroUpdates(to: .main) { (data, error) in
    // Handle rotation update
}

CMGyroData and Rotation

The gyroData variable on a CMMotionManager is a CMGyroData class. CMGyroData also contains a timestamp, in addition to rotationRate:

// Time the gyroscope reading was taken
gyroData.timestamp

// Device rotation values
gyroData.rotationRate.x
gyroData.rotationRate.y
gyroData.rotationRate.z

iOS Magnetometer Example

The magnetometer sensor reads magnetic fields. To read magnetometer data first create a CMMotionManager instance. Then, use the magnetometerData property to read the most recent magnetometer value or the startMagnetometerUpdates(to:) method to start magnetometer updates:

// Create a CMMotionManager instance
let manager = CMMotionManager()

// Read the most recent magnetometer value
manager.magnetometerData?.magneticField.x
manager.magnetometerData?.magneticField.y
manager.magnetometerData?.magneticField.z

// How frequently to read magnetometer updates,
// in seconds
manager.magnetometerUpdateInterval = 0.1

// Start receiving magnetometer updates
// on a specific thread
manager.startMagnetometerUpdates(to: .main) { (data, error) in
    // Handle magnetic field update
}

CMMagnetometerData and Magnetic Field

The magnetometerData variable on a CMMotionManager is a CMMagnetometerData class. CMMagnetometerData also contains a timestamp, in addition to magneticField:

// Time the magnetometer reading was taken
magnetometerData.timestamp

// Device magnetic field values
magnetometerData.magneticField.x
magnetometerData.magneticField.y
magnetometerData.magneticField.z

CMMotionManager Real-Time Updates Example

CMMotionManager has a convenient API to handle real-time updates from all motion sensors called startDeviceMotionUpdates(to:):

let manager = CMMotionManager()
manager.deviceMotionUpdateInterval = 0.1
manager.startDeviceMotionUpdates(to: .main) { (motion, error) in
    // Handle device motion updates
}

CMDeviceMotion

The startDeviceMotionUpdates(to:) handler block contains a motion argument, which is a CMDeviceMotion class. CMDeviceMotion contains a timestamp, and variables to access sensor data from each sensor:

// Get accelerometer sensor data
motion.userAcceleration.x
motion.userAcceleration.y
motion.userAcceleration.z

// Get gyroscope sensor data
motion.rotationRate.x
motion.rotationRate.y
motion.rotationRate.z

// Get magnetometer sensor data
motion.magneticField.accuracy
motion.magneticField.field.x
motion.magneticField.field.y
motion.magneticField.field.z

CMDeviceMotion Roll, Pitch, and Yaw

In addition to raw rotation, CMDeviceMotion also contains attitude. Attitude is the orientation of the device:

// Get attitude orientation
motion.attitude.pitch
motion.attitude.roll
motion.attitude.yaw

CMDeviceMotion Gravity

The gravity on CMDeviceMotion property describes the gravity vector relative to the device’s current orientation:

// Get gravity vector
motion.gravity.x
motion.gravity.y
motion.gravity.z

Read Motion Sensor Data on iOS in Swift

That’s it! By using CMMotionManager you can read acceleration, rotation, and magnetic field data from the motion sensors on iOS in Swift.