Core Motion의 공식 문서와 WWDC23 영상을 보고 공부한 내용을 기반으로 정리한 내용입니다.
공식문서
https://developer.apple.com/documentation/coremotion
Core Motion | Apple Developer Documentation
Process accelerometer, gyroscope, pedometer, and environment-related events.
developer.apple.com
관련 WWDC 영상 (2023년)
https://developer.apple.com/wwdc23/10179
What’s new in Core Motion - WWDC23 - Videos - Apple Developer
Learn how you can use the latest Core Motion updates to expand how your app uses motion data. Discover how to stream higher-frequency...
developer.apple.com
1. Core Motion이란?
Core Motion은 가속도계, 자이로스코프 등 여러 iOS 장치의 하드웨어에서 동작 관련 데이터 및 이벤트를 추적하고 사용할 수 있도록 해주는 프레임워크입니다.

2. CMMotionManager
모션 서비스를 시작하고 관리하기 위한 객체입니다.
기기의 센서에 의해 감지되는 정보를 활용하려면 해당 클래스의 인스턴스를 만들어주어야 합니다.
CMMotionManager로 받을 수 있는 모션 데이터는 4가지 종류가 존재합니다.
- Accelerometer(가속도계) 데이터 : 3차원 공간에서 기기의 순간 가속도를 나타내는 데이터
- Gyroscope(자이로스코프) 데이터 : 기기의 3가지 주요 축 주변의 즉각적인 회전을 나타내는 데이터
- Magnetometer(자력계) 데이터 : 지구의 자기장에 대한 기기의 방향을 나타내는 데이터
- Device-motion 데이터 : 위의 데이터들에 대해 Core Motion의 센서 융합 알고리즘을 적용해서 가공된 채로 제공되는 데이터
⇒ 실질적으로 사용자가 기기에 부여하는 센서값을 활용하고자 한다면 Device-motion 데이터를 사용하면 됩니다.
⚠️ 하나의 앱에서 CMMotionManager 객체는 1개만 만들어야 합니다.
→ 여러 개의 인스턴스를 생성하게 되면 가속도계와 자이로스코프로부터 데이터를 받는 속도에 영향을 미칠 수 있음
CMMotionManager를 사용하면 지정된 업데이트 간격으로 실시간 센서 데이터를 수집할 수 있습니다.
지정된 간격으로 센서 데이터를 수집하고자 한다면 아래의 3가지를 적용해줍니다.
- 업데이트 간격을 지정하기 위한 interval 프로퍼티 값 설정
- 업데이트 시작을 위한 start 메서드 호출
- 업데이트 중지를 위한 stop 메서드 호출
수집하려는 데이터의 종류에 따라서 업데이트 간격 설정과 업데이트 시작/종료에 각각 다른 프로퍼티와 메서드를 사용합니다.
- Accelerometer
- accelerometerUpdateInterval : 업데이트 간격을 지정
- startAccelerometerUpdates(to:withHandler:) 메서드 : 가속도계 데이터는 CMAccelerometerHandler 타입의 withHandler 블록 안에서 CMAccelerometerData 타입의 객체로 전달됩니다.
- stopAccelerometerUpdates() : 업데이트 중지
- Gyroscope
- gyroUpdateInterval : 업데이트 간격을 지정
- startGyroUpdates(to:withHandler:) 메서드 : 회전 속도 데이터는 CMGyroHandler 타입의 withHandler 블록 안에서 CMGyroData 타입의 객체로 전달됩니다.
- stopGyroUpdates() : 업데이트 중지
- Magnetometer
- magnetometerUpdateInterval : 업데이트 간격을 지정
- startMagnetometerUpdates(to:withHandler:) 메서드 : 자기장 데이터는 CMMagnetometerHandler 타입의 withHandler 블록 안에서 CMMagnetometerData 타입의 객체로 전달됩니다.
- stopMagnetometerUpdates() : 업데이트 중지
- Device motion
- deviceMotionUpdateInterval : 업데이트 간격을 지정
- startDeviceMotionUpdates(using:) 또는 startDeviceMotionUpdates(using:to:withHandler) 또는 startDeviceMotionUpdates(to:withHandler:) 메서드 : device motion 데이터는 CMDeviceMotionHandler 타입의 withHandler 블록 안에서 CMDevicecMotion 타입의 객체로 전달됩니다.
- stopDeviceMotionUpdates() : 업데이트 중지
하드웨어 가용성 및 상태 확인
가속도계, 자이로스코프 같은 하드웨어 기능을 기기에서 사용할 수 없는 경우, 해당 기능과 관련된 start 메서드를 호출하는 것은 효과가 없습니다. 그렇기 때문에 해당 센서값이 현재 기기에서 가용한지 또는 활성화 되어 있는지를 확인해주는 것이 좋습니다.
- 서비스의 가용성 확인
// device-motion 서비스가 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isDeviceMotionAvailable: Bool
// 가속도계가 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isAccelerometerAvailable: Bool
// 자이로스코프가 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isGyroAvailable: Bool
// 자력계를 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isMagnetometerAvailable: Bool
- 어떤 서비스가 활성화 되어 있는지 확인
// 앱이 device-motion 서비스로부터 업데이트를 받고 있는지 여부를 나타내는 Bool 타입 값
var isDeviecMotionActive: Bool
// 현재 가속도계 업데이트가 발생하고 있는지 여부를 나타내는 Bool 타입 값
var isAccelerometerActive: Bool
// 현재 자이로스코프 업데이트가 발생하고 있는지 여부를 나타내는 Bool 타입 값
var isGyroActive: Bool
// 현재 자력계 업데이트가 발생하고 있는지 여부를 나타내는 Bool 타입 값
var isMagnetometerActive: Bool
3. Core Motion 활용 예제 코드
CoreMotion 프레임워크를 사용해서 지정한 간격에 맞게 device motion 데이터를 추적하는 코드를 작성해보겠습니다.
- 먼저 CoreMotion 프레임워크를 임포트 해줍니다.
import CoreMotion
- CMMotionManager() 인스턴스를 생성해줍니다.
let motionManager = CMMotionManager()
- device motion을 현재 기기에서 수집 가능한지 확인해줍니다.
guard motionManager.isDeviceMotionAvailable else {
print("Device motion data is not available")
return
}
- 모션 갱신 주기를 설정해줍니다.
- Interval 값은 1개의 데이터값이 수집되는데 걸리는 시간을 의미합니다.
- 0.1 (1/10) ⇒ 초당 10개의 데이터 수집을 의미합니다. (10Hz)
motionManager.deviceMotionUpdateInterval = 0.1
- device motion 업데이트를 받기 시작합니다.
motionManager.startDeviceMotionUpdates(to: .main) { (deviceMotion: CMDeviceMotion?, error: Error?) in
guard let data = deviceMotion, error == nil else {
print("Failed to get device motion data: \(error?.localizedDescription ?? "Unknown error")")
return
}
// 필요한 센서값 불러오기
let acceleration = data.userAcceleration // device motion 데이터 중 가속도계 데이터 불러오기
/**
해당 센서값을 활용하여 원하는 동작을 처리해줍니다.
*/
}
- device motion 업데이트를 중지합니다.
motionManager.stopDeviceMotionUpdates()
위 내용들이 적용된 샘플 코드입니다.
/* watchOS에서 Core Motion 데이터 수집하기 */
import SwiftUI
import CoreMotion
struct ContentView: View {
@State var accX = 0.0
@State var accY = 0.0
@State var accZ = 0.0
private let motionManager = CMMotionManager()
var body: some View {
VStack {
Text("Acceleration")
Text("X: \(accX)")
Text("Y: \(accY)")
Text("Z: \(accZ)")
HStack {
Button {
startRecordingDeviceMotion()
print("Device motion 업데이트 시작!!!")
} label: {
Text("Start")
.font(.body)
.foregroundColor(.green)
}
Button {
stopRecordingDeviceMotion()
print("Device motion 업데이트 종료!!!")
} label: {
Text("Stop")
.font(.body)
.foregroundColor(.red)
}
}
}
}
}
extension ContentView {
func startRecordingDeviceMotion() {
// Device motion을 수집 가능한지 확인
guard motionManager.isDeviceMotionAvailable else {
print("Device motion data is not available")
return
}
// 모션 갱신 주기 설정 (10Hz)
motionManager.deviceMotionUpdateInterval = 0.1
// Device motion 업데이트 받기 시작
motionManager.startDeviceMotionUpdates(to: .main) { (deviceMotion: CMDeviceMotion?, error: Error?) in
guard let data = deviceMotion, error == nil else {
print("Failed to get device motion data: \(error?.localizedDescription ?? "Unknown error")")
return
}
// 필요한 센서값 불러오기
let acceleration = data.userAcceleration
accX = acceleration.x
accY = acceleration.y
accZ = acceleration.z
}
}
func stopRecordingDeviceMotion() {
motionManager.stopDeviceMotionUpdates()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
- Start 버튼을 누르면 Device motion 센서값을 업데이트 하기 시작하며, 애플워치의 화면에 x,y,z 각각의 축에 대한 가속도계 값이 표시됩니다.
- Stop 버튼을 누르면 업데이트를 중지합니다.

'iOS' 카테고리의 다른 글
[ iOS ] 팀 작업 시에 Bundle Identifier 하나로 공유하기 (0) | 2023.08.27 |
---|---|
[ iOS ] Watch Connectivity 사용해보기 (0) | 2023.08.08 |
[ iOS ] Swift Package(.swiftpm)에서 .mlmodel 모델 불러오기 (0) | 2023.04.22 |
[ iOS ] Xcode 프로젝트 기본 생성 파일 설명 (14.2 버전 기준, UIKit) (0) | 2023.03.06 |
[ iOS ] Xcode로 iOS 개발 시 API KEY 숨기기 (0) | 2023.03.01 |
Core Motion의 공식 문서와 WWDC23 영상을 보고 공부한 내용을 기반으로 정리한 내용입니다.
공식문서
https://developer.apple.com/documentation/coremotion
Core Motion | Apple Developer Documentation
Process accelerometer, gyroscope, pedometer, and environment-related events.
developer.apple.com
관련 WWDC 영상 (2023년)
https://developer.apple.com/wwdc23/10179
What’s new in Core Motion - WWDC23 - Videos - Apple Developer
Learn how you can use the latest Core Motion updates to expand how your app uses motion data. Discover how to stream higher-frequency...
developer.apple.com
1. Core Motion이란?
Core Motion은 가속도계, 자이로스코프 등 여러 iOS 장치의 하드웨어에서 동작 관련 데이터 및 이벤트를 추적하고 사용할 수 있도록 해주는 프레임워크입니다.

2. CMMotionManager
모션 서비스를 시작하고 관리하기 위한 객체입니다.
기기의 센서에 의해 감지되는 정보를 활용하려면 해당 클래스의 인스턴스를 만들어주어야 합니다.
CMMotionManager로 받을 수 있는 모션 데이터는 4가지 종류가 존재합니다.
- Accelerometer(가속도계) 데이터 : 3차원 공간에서 기기의 순간 가속도를 나타내는 데이터
- Gyroscope(자이로스코프) 데이터 : 기기의 3가지 주요 축 주변의 즉각적인 회전을 나타내는 데이터
- Magnetometer(자력계) 데이터 : 지구의 자기장에 대한 기기의 방향을 나타내는 데이터
- Device-motion 데이터 : 위의 데이터들에 대해 Core Motion의 센서 융합 알고리즘을 적용해서 가공된 채로 제공되는 데이터
⇒ 실질적으로 사용자가 기기에 부여하는 센서값을 활용하고자 한다면 Device-motion 데이터를 사용하면 됩니다.
⚠️ 하나의 앱에서 CMMotionManager 객체는 1개만 만들어야 합니다.
→ 여러 개의 인스턴스를 생성하게 되면 가속도계와 자이로스코프로부터 데이터를 받는 속도에 영향을 미칠 수 있음
CMMotionManager를 사용하면 지정된 업데이트 간격으로 실시간 센서 데이터를 수집할 수 있습니다.
지정된 간격으로 센서 데이터를 수집하고자 한다면 아래의 3가지를 적용해줍니다.
- 업데이트 간격을 지정하기 위한 interval 프로퍼티 값 설정
- 업데이트 시작을 위한 start 메서드 호출
- 업데이트 중지를 위한 stop 메서드 호출
수집하려는 데이터의 종류에 따라서 업데이트 간격 설정과 업데이트 시작/종료에 각각 다른 프로퍼티와 메서드를 사용합니다.
- Accelerometer
- accelerometerUpdateInterval : 업데이트 간격을 지정
- startAccelerometerUpdates(to:withHandler:) 메서드 : 가속도계 데이터는 CMAccelerometerHandler 타입의 withHandler 블록 안에서 CMAccelerometerData 타입의 객체로 전달됩니다.
- stopAccelerometerUpdates() : 업데이트 중지
- Gyroscope
- gyroUpdateInterval : 업데이트 간격을 지정
- startGyroUpdates(to:withHandler:) 메서드 : 회전 속도 데이터는 CMGyroHandler 타입의 withHandler 블록 안에서 CMGyroData 타입의 객체로 전달됩니다.
- stopGyroUpdates() : 업데이트 중지
- Magnetometer
- magnetometerUpdateInterval : 업데이트 간격을 지정
- startMagnetometerUpdates(to:withHandler:) 메서드 : 자기장 데이터는 CMMagnetometerHandler 타입의 withHandler 블록 안에서 CMMagnetometerData 타입의 객체로 전달됩니다.
- stopMagnetometerUpdates() : 업데이트 중지
- Device motion
- deviceMotionUpdateInterval : 업데이트 간격을 지정
- startDeviceMotionUpdates(using:) 또는 startDeviceMotionUpdates(using:to:withHandler) 또는 startDeviceMotionUpdates(to:withHandler:) 메서드 : device motion 데이터는 CMDeviceMotionHandler 타입의 withHandler 블록 안에서 CMDevicecMotion 타입의 객체로 전달됩니다.
- stopDeviceMotionUpdates() : 업데이트 중지
하드웨어 가용성 및 상태 확인
가속도계, 자이로스코프 같은 하드웨어 기능을 기기에서 사용할 수 없는 경우, 해당 기능과 관련된 start 메서드를 호출하는 것은 효과가 없습니다. 그렇기 때문에 해당 센서값이 현재 기기에서 가용한지 또는 활성화 되어 있는지를 확인해주는 것이 좋습니다.
- 서비스의 가용성 확인
// device-motion 서비스가 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isDeviceMotionAvailable: Bool
// 가속도계가 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isAccelerometerAvailable: Bool
// 자이로스코프가 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isGyroAvailable: Bool
// 자력계를 기기에서 사용 가능한지 여부를 나타내는 Bool 타입 값
var isMagnetometerAvailable: Bool
- 어떤 서비스가 활성화 되어 있는지 확인
// 앱이 device-motion 서비스로부터 업데이트를 받고 있는지 여부를 나타내는 Bool 타입 값
var isDeviecMotionActive: Bool
// 현재 가속도계 업데이트가 발생하고 있는지 여부를 나타내는 Bool 타입 값
var isAccelerometerActive: Bool
// 현재 자이로스코프 업데이트가 발생하고 있는지 여부를 나타내는 Bool 타입 값
var isGyroActive: Bool
// 현재 자력계 업데이트가 발생하고 있는지 여부를 나타내는 Bool 타입 값
var isMagnetometerActive: Bool
3. Core Motion 활용 예제 코드
CoreMotion 프레임워크를 사용해서 지정한 간격에 맞게 device motion 데이터를 추적하는 코드를 작성해보겠습니다.
- 먼저 CoreMotion 프레임워크를 임포트 해줍니다.
import CoreMotion
- CMMotionManager() 인스턴스를 생성해줍니다.
let motionManager = CMMotionManager()
- device motion을 현재 기기에서 수집 가능한지 확인해줍니다.
guard motionManager.isDeviceMotionAvailable else {
print("Device motion data is not available")
return
}
- 모션 갱신 주기를 설정해줍니다.
- Interval 값은 1개의 데이터값이 수집되는데 걸리는 시간을 의미합니다.
- 0.1 (1/10) ⇒ 초당 10개의 데이터 수집을 의미합니다. (10Hz)
motionManager.deviceMotionUpdateInterval = 0.1
- device motion 업데이트를 받기 시작합니다.
motionManager.startDeviceMotionUpdates(to: .main) { (deviceMotion: CMDeviceMotion?, error: Error?) in
guard let data = deviceMotion, error == nil else {
print("Failed to get device motion data: \(error?.localizedDescription ?? "Unknown error")")
return
}
// 필요한 센서값 불러오기
let acceleration = data.userAcceleration // device motion 데이터 중 가속도계 데이터 불러오기
/**
해당 센서값을 활용하여 원하는 동작을 처리해줍니다.
*/
}
- device motion 업데이트를 중지합니다.
motionManager.stopDeviceMotionUpdates()
위 내용들이 적용된 샘플 코드입니다.
/* watchOS에서 Core Motion 데이터 수집하기 */
import SwiftUI
import CoreMotion
struct ContentView: View {
@State var accX = 0.0
@State var accY = 0.0
@State var accZ = 0.0
private let motionManager = CMMotionManager()
var body: some View {
VStack {
Text("Acceleration")
Text("X: \(accX)")
Text("Y: \(accY)")
Text("Z: \(accZ)")
HStack {
Button {
startRecordingDeviceMotion()
print("Device motion 업데이트 시작!!!")
} label: {
Text("Start")
.font(.body)
.foregroundColor(.green)
}
Button {
stopRecordingDeviceMotion()
print("Device motion 업데이트 종료!!!")
} label: {
Text("Stop")
.font(.body)
.foregroundColor(.red)
}
}
}
}
}
extension ContentView {
func startRecordingDeviceMotion() {
// Device motion을 수집 가능한지 확인
guard motionManager.isDeviceMotionAvailable else {
print("Device motion data is not available")
return
}
// 모션 갱신 주기 설정 (10Hz)
motionManager.deviceMotionUpdateInterval = 0.1
// Device motion 업데이트 받기 시작
motionManager.startDeviceMotionUpdates(to: .main) { (deviceMotion: CMDeviceMotion?, error: Error?) in
guard let data = deviceMotion, error == nil else {
print("Failed to get device motion data: \(error?.localizedDescription ?? "Unknown error")")
return
}
// 필요한 센서값 불러오기
let acceleration = data.userAcceleration
accX = acceleration.x
accY = acceleration.y
accZ = acceleration.z
}
}
func stopRecordingDeviceMotion() {
motionManager.stopDeviceMotionUpdates()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
- Start 버튼을 누르면 Device motion 센서값을 업데이트 하기 시작하며, 애플워치의 화면에 x,y,z 각각의 축에 대한 가속도계 값이 표시됩니다.
- Stop 버튼을 누르면 업데이트를 중지합니다.

'iOS' 카테고리의 다른 글
[ iOS ] 팀 작업 시에 Bundle Identifier 하나로 공유하기 (0) | 2023.08.27 |
---|---|
[ iOS ] Watch Connectivity 사용해보기 (0) | 2023.08.08 |
[ iOS ] Swift Package(.swiftpm)에서 .mlmodel 모델 불러오기 (0) | 2023.04.22 |
[ iOS ] Xcode 프로젝트 기본 생성 파일 설명 (14.2 버전 기준, UIKit) (0) | 2023.03.06 |
[ iOS ] Xcode로 iOS 개발 시 API KEY 숨기기 (0) | 2023.03.01 |