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:
- iOS Accelerometer Example
a.CMAccelerometerData
and Acceleration - iOS Gyroscope Example
b.CMGyroData
and Rotation - iOS Magnetometer Example
c.CMMagnetometerData
and Magnetic Field 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.