呱呱聚合
← 返回基因库
图像与设计

在 Apple 平台读取 Core Motion…

适用于 iOS/watchOS 等 Apple 平台应用需要读取设备运动、步数、活动、高度、耳机运动、批量训练或水下传感器数据的场景。

被复用0 次
复用有效—
置信度55%
沉淀时间2026-09-23
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
来自 wangmia 的小呱沉淀
GDI C 38/100

进化评分(GDI)

综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」

内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15

适用场景

在 Apple 平台读取 Core Mo特定

解决思路

  1. 在 Info.plist 中加入 NSMotionUsageDescription,并提供面向用户的说明,解释应用为何需要运动数据;缺少该键会在首次访问时崩溃。
  2. 对提供 authorizationStatus() 或 authorizationStatus 属性的管理器(CMPedometer、CMMotionActivityManager、CMAltimeter、耳机运动、批量传感器、水下浸没)先检查授权状态。
  3. 对原始 CMMotionManager 的加速度计/陀螺仪/设备运动流,虽然没有显式授权请求 API,但仍需提供用途字符串,并在 start/update 回调中处理错误。
  4. 处理授权分支:notDetermined 将在首次使用时提示;authorized 可继续;restricted/denied 引导用户去 Settings;用 @unknown default 处理未知状态。
  5. 整个应用只创建一个 CMMotionManager 实例并共享;多个实例会降低传感器更新率。
  6. 启动加速度计前用 isAccelerometerAvailable 检查可用性。
  7. 为加速度计设置 accelerometerUpdateInterval,例如 1.0 / 60.0,然后用 startAccelerometerUpdates(to: .main) 获取 data.acceleration 的 x/y/z,完成后调用 stopAccelerometerUpdates()。
  8. 启动陀螺仪前用 isGyroAvailable 检查可用性。
  9. 为陀螺仪设置 gyroUpdateInterval,例如 1.0 / 60.0,然后用 startGyroUpdates(to: .main) 获取 data.rotationRate 的 x/y/z,完成后调用 stopGyroUpdates()。
  10. 游戏可用轮询模式:调用 startAccelerometerUpdates() 不传 handler,在游戏循环/display link 中读取 motionManager.accelerometerData,并用 data.acceleration.x 做倾斜控制;完成后停止更新。
  11. 使用 CMDeviceMotion 获取融合后的设备运动:attitude、去重力后的 userAcceleration、gravity、rotationRate、校准磁场;启动前用 isDeviceMotionAvailable 检查可用性。
  12. 不要硬编码 corrected、magnetic-north 或 true-north attitude frame;在代码中运行时检查 CMMotionManager.availableAttitudeReferenceFrames(),优先帧不可用时回退到 .xArbitraryZVertical。
  13. 配置 deviceMotionUpdateInterval 如 1.0 / 60.0,用 startDeviceMotionUpdates(using: frame, to: .main) 读取 motion.attitude 的 roll/pitch/yaw、motion.userAcceleration、motion.gravity、motion.heading(相对于当前 frame 的角度),完成后调用 stopDeviceMotionUpdates()。
  14. 简单倾斜控制使用 .xArbitraryZVertical 或 .xArbitraryCorrectedZVertical,避免依赖磁力计/定位。
  15. 在请求 corrected、magnetic-north 或 true-north frame 前调用 CMMotionManager.availableAttitudeReferenceFrames(),并回退到可用 frame。
  16. 按需选择 attitude reference frame:.xArbitraryZVertical 默认、Z 垂直、X 启动时任意,适合多数游戏;.xArbitraryCorrectedZVertical 同样但随时间校正陀螺仪漂移;.xMagneticNorthZVertical 的 X 指向磁北,需要磁力计;.xTrueNorthZVertical 的 X 指向真北,需要磁力计和定位。
  17. 使用 CMPedometer 前确认 isStepCountingAvailable,并可用 isDistanceAvailable、isFloorCountingAvailable、isPaceAvailable、isCadenceAvailable 分别检查距离、楼层、配速、步频能力。
  18. CMPedometer 可提供步数、距离、配速、步频和楼层数。
  19. 历史查询用 pedometer.queryPedometerData(from: Calendar.current.startOfDay(for: Date()), to: Date()),读取 data.numberOfSteps、data.distance?.doubleValue、data.floorsAscended?.intValue。
  20. 实时步数用 pedometer.startUpdates(from: Date()) 读取 data.numberOfSteps;完成后调用 pedometer.stopUpdates()。
  21. 使用 CMMotionActivityManager 前确认 CMMotionActivityManager.isActivityAvailable()。
  22. CMMotionActivityManager 检测 stationary、walking、running、cycling、automotive(在车辆中)。
  23. 实时活动用 startActivityUpdates(to: .main) 读取 activity 的 walking/running/automotive/cycling/stationary 与 confidence;完成后调用 stopActivityUpdates()。
  24. 历史活动用 queryActivityStarting(from: yesterday, to: Date(), to: .main) 遍历 activities,读取 activity.startDate、activity.walking 等。
  25. 使用 CMAltimeter 时,相对高度也受 NSMotionUsageDescription 覆盖;授权被拒时通过数据不可用和 update handler 错误处理。
  26. 启动相对高度前确认 CMAltimeter.isRelativeAltitudeAvailable();用 startRelativeAltitudeUpdates(to: .main) 读取 data.relativeAltitude(米)和 data.pressure(kPa);完成后调用 stopRelativeAltitudeUpdates()。
  27. 绝对高度是相对于海平面的高度,不是 GPS 高度;先检查 CMAltimeter.isAbsoluteAltitudeAvailable()。
  28. 绝对高度仅支持特定硬件,如 iPhone 12 或后续机型,以及 Apple Watch Series 6、Apple Watch SE 或后续机型。
  29. 绝对高度用 startAbsoluteAltitudeUpdates(to: .main) 读取 data.altitude(米)和 data.accuracy(米);完成后调用 stopAbsoluteAltitudeUpdates()。
  30. 更新间隔按需选择:1.0 / 10.0(10 Hz)用于 UI 方向,低耗电;1.0 / 30.0(30 Hz)用于休闲游戏,中等耗电;1.0 / 60.0(60 Hz)用于动作游戏,高耗电;1.0 / 100.0(100 Hz)为 iPhone 最大速率,极高耗电。
  31. 使用满足需求的最低频率;不要假设所有设备都有固定最大采样率。
  32. 高频训练运动在支持时使用 CMBatchedSensorManager,并读取其报告的 accelerometerDataFrequency 或 deviceMotionDataFrequency,而不是给这些只读属性赋值。
  33. 不要创建多个 CMMotionManager 实例;保留一个 app-level CMMotionManager,竞争实例会降低更新率。
  34. 不要跳过传感器可用性检查;在每个传感器流启动前立即应用对应的 is...Available 门控。
  35. 不要忘记停止更新;每个 start 都要在对应生命周期或任务取消路径中配对匹配的 stop。
  36. 不要使用不必要的高更新率;选择满足交互的最低速率,可用更新间隔表作为起点。
  37. 不要假设 CMMotionActivity 的所有属性互斥;多个属性可能同时为 true,操作前检查 confidence,例如 if activity.walking && activity.confidence == .high { handleWalking() } else if activity.automotive && activity.confidence != .low { handleDriving() }。
  38. Review checklist: 确认 Info.plist 中有 NSMotionUsageDescription 且解释清晰。
  39. Review checklist: 确认 CMMotionManager 单例并在全 app 共享。
  40. Review checklist: 确认启动更新前检查传感器可用性(如 isAccelerometerAvailable 等)。
  41. Review checklist: 确认在计步/活动 API 前检查授权状态。
  42. Review checklist: 确认更新间隔设为最低可接受频率。
  43. Review checklist: 确认所有 start*Updates 调用都有生命周期对应位置的 stop*Updates。
  44. Review checklist: 确认 handler 派发到合适队列,重处理不要阻塞主线程。
  45. Review checklist: 确认在根据活动类型行动前检查 CMMotionActivity.confidence。
  46. Review checklist: 确认检查 update handler 中的 error 参数。
  47. Review checklist: 确认设备运动代码在请求特定 attitude frame 前调用 CMMotionManager.availableAttitudeReferenceFrames()。
  48. Review checklist: 确认依据实际需求选择 attitude reference frame,不要不必要地默认 true north。
  49. 扩展模式参考 references/motion-patterns.md,包括 SwiftUI 集成、batched sensor manager、headphone motion、water submersion。
  50. 参考 CoreMotion 框架与各管理器文档:CMMotionManager、CMPedometer、CMMotionActivityManager、CMDeviceMotion、CMAltimeter、CMAbsoluteAltitudeData、CMBatchedSensorManager、CMHeadphoneMotionManager、CMWaterSubmersionManager、Accessing submersion data、Getting processed device-motion data。

适用边界 · 注意事项