如何从Health Store获取最高采样率的历史心率数据?
解决Health Store心率数据细粒度读取与高频数据获取问题
1. 读取Quantity Series中的单个心率数据点
你提到的Quantity Series确实是存储连续心率数据的容器,普通的HKSampleQuery只能返回样本的元数据(比如起止时间、单位),无法直接读取其中的单个数据点。要获取系列内的每个BPM数据,需要使用HKQuantitySeriesQuery。
具体实现步骤:
- 先通过
HKSampleQuery获取HKQuantitySeriesSample实例(需做类型转换) - 针对每个系列样本,创建
HKQuantitySeriesQuery读取内部所有数据点
修改后的代码示例:
public func fetchHeartRateSeriesData(completion: @escaping ([(date: Date, bpm: Double)]?) -> Void) { guard let heartRateType = HKObjectType.quantityType(forIdentifier: .heartRate) else { completion(nil) return } let predicate = HKQuery.predicateForSamples(withStart: Date.distantPast, end: Date(), options: .strictEndDate) let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false) // 先查询所有心率系列样本 let sampleQuery = HKSampleQuery(sampleType: heartRateType, predicate: predicate, limit: Int(HKObjectQueryNoLimit), sortDescriptors: [sortDescriptor]) { _, results, error in guard let samples = results as? [HKQuantitySample], error == nil else { completion(nil) return } var allHeartRateData: [(date: Date, bpm: Double)] = [] let group = DispatchGroup() // 遍历每个系列样本,读取内部数据点 for sample in samples { guard let seriesSample = sample as? HKQuantitySeriesSample else { continue } group.enter() let seriesQuery = HKQuantitySeriesQuery(quantitySeries: seriesSample) { _, timeInterval, quantity, done, error in guard let quantity = quantity, error == nil else { group.leave() return } // 转换单位:counts per second → beats per minute let bpm = quantity.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.second())) * 60 let dataPointDate = seriesSample.startDate.addingTimeInterval(timeInterval) allHeartRateData.append((date: dataPointDate, bpm: bpm)) if done { group.leave() } } self.healthStore.execute(seriesQuery) } group.notify(queue: .main) { // 按时间排序(可选,根据需求调整) let sortedData = allHeartRateData.sorted { $0.date < $1.date } completion(sortedData) } } healthStore.execute(sampleQuery) }
关键说明:
HKQuantitySeriesQuery的回调会逐次返回系列内的每个数据点,timeInterval是数据点相对于样本起始时间的偏移量- 心率数据默认存储单位为
counts per second,需乘以60转换为常用的BPM单位 - 使用
DispatchGroup处理多个异步查询的结果汇总,确保所有数据读取完成后再返回
2. 高频心率数据的获取条件
要拿到5-10秒间隔的心率数据,必须满足以下条件:
- 用户佩戴的Apple Watch已开启连续心率监测(在iPhone的Watch应用「心率」设置中开启)
- 用户处于活动状态(如运动),此时Watch会自动提高心率采样频率;静态状态下采样间隔会变长(可能1分钟甚至更久)
- 设备处于正常佩戴状态,心率传感器能正常采集数据
3. Apple是否默认存储高频心率数据?
不会默认存储所有高频数据:
- 只有当设备满足上述监测条件(佩戴、开启连续监测、活动状态)时,Watch才会记录高频心率数据并同步到Health Store
- 如果用户未开启连续心率监测,或设备未佩戴,Health Store中只会有低频率的心率数据(比如每几分钟一次)
- 你无法获取Health Store中不存在的数据,必须依赖设备实际记录并同步的数据
内容的提问来源于stack exchange,提问作者CofeeBean42
相关产品推荐
相关产品推荐

