Apple Watch息屏时如何记录运动?CMMotionManager使用求助
解决Apple Watch息屏时CMMotionManager记录暂停的问题
我之前也踩过这个坑,给你两个实用的解决方案,分别对应不同的使用场景:
方案一:让屏幕保持常亮(适合短时间记录)
watchOS的Always On模式可以让屏幕在手腕下垂(通常触发息屏的动作)时保持低亮度显示,这样运动数据的记录就不会中断。
在你的WKInterfaceController里添加这段代码就能开启:
override func willActivate() { super.willActivate() // 开启Always On模式,避免手腕下垂触发息屏 WKInterfaceDevice.current().isAlwaysOnEnabled = true }
⚠️ 注意:这个模式会小幅增加耗电量,如果是数小时级的长时间记录,更推荐下面的后台方案。
方案二:息屏状态下后台持续记录(适合长时间场景)
要实现息屏后不中断记录,需要配置权限+利用扩展运行会话,具体步骤如下:
配置项目权限
- 打开Xcode,选中你的WatchKit Extension目标,进入
Signing & Capabilities标签页 - 开启
Background Modes,勾选Motion & Fitness选项 - 在Extension的
Info.plist中添加NSMotionUsageDescription键,填写申请运动权限的原因(比如"需要记录你的姿态数据以完成运动分析功能")
- 打开Xcode,选中你的WatchKit Extension目标,进入
让CMMotionManager在后台工作
确保运动数据的更新逻辑在后台队列中执行,示例代码:
import CoreMotion class MotionRecorder { private let motionManager = CMMotionManager() private let backgroundQueue = DispatchQueue(label: "com.yourapp.motion-processing") func startRecording() { // 先请求用户授权 motionManager.requestDeviceMotionAuthorization { authStatus in guard authStatus == .authorized else { // 处理权限被拒绝的情况,比如提示用户开启权限 return } // 设置更新间隔(根据需求调整,这里是100ms一次) self.motionManager.deviceMotionUpdateInterval = 0.1 // 在后台队列接收姿态数据更新 self.motionManager.startDeviceMotionUpdates(to: self.backgroundQueue) { motion, error in guard let validMotion = motion else { // 处理更新错误 return } // 这里处理姿态数据,比如保存到本地或同步到iPhone let attitude = validMotion.attitude print("Roll: \(attitude.roll), Pitch: \(attitude.pitch), Yaw: \(attitude.yaw)") } } } func stopRecording() { motionManager.stopDeviceMotionUpdates() } }
- 用WKExtendedRuntimeSession延长后台运行时间
默认后台运行时长有限,如果需要长时间记录,需要申请扩展运行会话:
import WatchKit class YourInterfaceController: WKInterfaceController, WKExtendedRuntimeSessionDelegate { private let extendedSession = WKExtendedRuntimeSession() private let motionRecorder = MotionRecorder() override func willActivate() { super.willActivate() startExtendedBackgroundSession() } private func startExtendedBackgroundSession() { extendedSession.delegate = self extendedSession.start() } // MARK: - WKExtendedRuntimeSessionDelegate func extendedRuntimeSessionDidStart(_ session: WKExtendedRuntimeSession) { // 会话启动后开始记录姿态数据 motionRecorder.startRecording() } func extendedRuntimeSession(_ session: WKExtendedRuntimeSession, didInvalidateWith reason: WKExtendedRuntimeSessionInvalidationReason, error: Error?) { // 会话失效时停止记录,比如超时、用户关闭应用等情况 motionRecorder.stopRecording() // 根据失效原因做对应处理 } }
关键提醒
- 一定要在真实Apple Watch设备上测试,模拟器的后台行为和真机差异很大
- 扩展运行会话最长支持180分钟左右,系统会根据设备电量、当前负载等情况决定是否批准请求
- 后台记录时尽量减少不必要的计算和UI操作,避免被系统强制终止
内容的提问来源于stack exchange,提问作者user7277596
相关产品推荐
相关产品推荐

