HealthKit如何查询同时获取HKQuantitySample和HKCumulativeQuantitySample心率样本
Apple Health心率查询兼容HKCumulativeQuantitySample类型调整方案
问题根源
你的原有代码仅支持捕获离散格式的HKQuantitySample心率样本,当有应用将心率以累积格式HKCumulativeQuantitySample存入健康库时,直接强转结果数组为[HKQuantitySample]的逻辑会直接丢弃所有累积类型的样本,导致数据缺失。
调整逻辑
- 取消对查询结果整体的强转操作,逐一遍历返回的
HKSample对象,分别匹配两种样本类型 - 按需处理
HKCumulativeQuantitySample的数值:可直接返回原始样本,也可将其转换为和HKQuantitySample格式统一的结构 - 可根据业务需要选择返回原始多类型样本,或是统一转换为单一格式的样本集合
调整后代码
class func getHeartRateSamplesFrom(workout: HKWorkout, handler: @escaping ([HKQuantitySample]?, WorkoutManagerError?) -> Void) { guard let heartRateType: HKQuantityType = HKQuantityType.quantityType(forIdentifier: .heartRate) else { handler(nil, .init(errorDescription: "心率类型不可用")) return } let predicate = HKQuery.predicateForSamples(withStart: workout.startDate, end: workout.endDate, options: .strictStartDate) let sortDescriptors = [NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)] let heartRateQuery = HKSampleQuery( sampleType: heartRateType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: sortDescriptors ) { query, results, error in guard error == nil else { print("获取心率数据失败: \(error!.localizedDescription)") handler(nil, .init(errorDescription: "查询失败")) return } guard let unwrappedResults = results else { handler([], nil) return } var heartRateSamples = [HKQuantitySample]() for sample in unwrappedResults { // 匹配离散心率样本 if let quantitySample = sample as? HKQuantitySample { heartRateSamples.append(quantitySample) } // 匹配累积心率样本,按需转换格式 else if let cumulativeSample = sample as? HKCumulativeQuantitySample { // 此处示例直接提取累积总和生成等效HKQuantitySample // 若业务需要平均心率,可自行计算时间段长度后换算 let convertedSample = HKQuantitySample( type: heartRateType, quantity: cumulativeSample.sumQuantity, start: cumulativeSample.startDate, end: cumulativeSample.endDate, device: cumulativeSample.device, metadata: cumulativeSample.metadata ) heartRateSamples.append(convertedSample) } } handler(heartRateSamples, nil) } HealthStoreSingleton.sharedInstance.healthStore.execute(heartRateQuery) }
注意事项
HKCumulativeQuantitySample存储的是某段时间内的心率总和,如果你的业务需要展示的是每个时间点的实时心率,可根据样本的时间跨度换算为平均心率后再生成新的样本。- 调用查询前请确保已经向用户申请了心率数据的读取权限,否则查询会返回空结果或权限错误。
内容的提问来源于stack exchange,提问作者GarySabo
相关产品推荐
相关产品推荐

