超越计步:深入 HealthKit 运动数据
Beyond counting steps
2020年6月24日
一句话判断
HealthKit 不只是存步数——iOS 14 新增了 Mobility(移动能力)数据类型和更精细的运动指标,配合 Apple Watch 的传感器数据,可以做真正的运动科学分析而不只是「今天走了多少步」。
这场 Session 讲了什么
这场 Session 聚焦于 HealthKit 在运动健康领域的深度应用,特别是 iOS 14 / watchOS 7 中新增的健康数据类型。
核心内容是 HealthKit 新增的 Mobility 数据类别,包含步速(Walking Speed)、步长(Step Length)、步行不对称性(Walking Asymmetry)、双支撑时间占比(Double Support Percentage)等精细指标。这些数据由 Apple Watch 的加速计和陀螺仪自动采集,无需 app 做任何传感器计算。
Session 还讲解了如何用 HKStatisticsCollectionQuery 查询长时间序列的运动数据、如何构建趋势图表、以及如何利用这些数据为用户提供有意义的健康洞察(比如「你的步速比上月下降了 5%,可能需要关注」)。
值得深挖的点
Mobility 指标的临床意义
步速(Walking Speed)是老年医学中评估整体健康状态的核心指标。研究表明步速低于 0.8m/s 与跌倒风险显著相关。Apple Watch 现在自动采集这个数据,你的 app 可以直接读取并做风险提示。步行不对称性(左右脚步长差异)则可以反映运动损伤或康复进展。这些数据以前需要专业设备在实验室里测,现在手表就能采集。
数据采集的自动化
这些 Mobility 数据是 Apple Watch 自动采集的,不需要 app 在后台运行或申请额外权限。你的 app 只需要请求 HealthKit 的读取权限(HKObjectType 对应的 sharing request),就可以读取历史数据。这意味着即使用户没有安装你的 app,Apple Watch 也在默默记录这些指标。
代码片段
import HealthKit
// 请求 HealthKit 权限并读取 Mobility 数据
class HealthDataManager {
let healthStore = HKHealthStore()
func requestAuthorization() {
let typesToRead: Set<HKObjectType> = [
HKObjectType.quantityType(forIdentifier: .walkingSpeed)!,
HKObjectType.quantityType(forIdentifier: .stepLength)!,
HKObjectType.quantityType(forIdentifier: .walkingAsymmetryPercentage)!,
HKObjectType.quantityType(forIdentifier: .walkingDoubleSupportPercentage)!,
HKObjectType.quantityType(forIdentifier: .stepCount)!
]
healthStore.requestAuthorization(toShare: nil, read: typesToRead) { success, error in
if success {
self.fetchMobilityTrend()
}
}
}
func fetchMobilityTrend() {
let speedType = HKQuantityType.quantityType(forIdentifier: .walkingSpeed)!
// 查询最近 30 天的步速数据
let startDate = Calendar.current.date(byAdding: .day, value: -30, to: Date())!
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
// 按天聚合,取平均值
let query = HKStatisticsCollectionQuery(
quantityType: speedType,
quantitySamplePredicate: predicate,
options: .discreteAverage,
anchorDate: startDate,
intervalComponents: DateComponents(day: 1)
)
query.initialResultsHandler = { _, results, error in
guard let results = results else { return }
results.enumerateStatistics(from: startDate, to: Date()) { statistics, _ in
if let avg = statistics.averageQuantity() {
let speed = avg.doubleValue(for: HKUnit.meter().unitDivided(by: .second()))
print("\(statistics.startDate): 步速 \(String(format: "%.2f", speed)) m/s")
}
}
}
healthStore.execute(query)
}
}
// 检测步速下降趋势并给出提示
func analyzeSpeedTrend() {
let speedType = HKQuantityType.quantityType(forIdentifier: .walkingSpeed)!
// 获取本月和上月的平均步速
let calendar = Calendar.current
let now = Date()
let thisMonthStart = calendar.date(from: calendar.dateComponents([.year, .month], from: now))!
let lastMonthStart = calendar.date(byAdding: .month, value: -1, to: thisMonthStart)!
// 比较两个月的数据...
// 如果本月步速比上月低超过 5%,提醒用户
let threshold: Double = 0.05
let warningSpeed: Double = 0.8 // 临床风险阈值
}
最佳实践
- 用
HKStatisticsCollectionQuery而不是逐条查询。HealthKit 中可能有成千上万条步速记录,按时间区间聚合后再分析,比把所有原始数据拉到内存再计算高效得多。 - 展示数据时给参考范围。单纯告诉用户「你的步速是 1.2m/s」没有意义。应该标注同年龄段平均水平(可以用「高于 70% 同龄人」这种形式),或者用绿/黄/红色标记风险等级。
- 注意数据稀疏性。用户不是每天都戴手表,有些天可能没有数据。查趋势时跳过无数据的天数,不要把缺失值当 0 处理。
还有什么值得关注
- watchOS 7 新增了
HKWheelchairUse对应的运动指标调整,轮椅用户的数据采集和展示有独立逻辑。 - HealthKit 的 Mobility 数据在 Apple Health app 的「移动能力」类别中也可以看到,你的 app 不需要独自承担数据采集。
- 所有 Mobility 数据都受 HealthKit 权限控制,用户可以选择性地授权你的 app 读取部分数据。