You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HealthKit获取最新心率时为何始终返回0?

解决HealthKit读取心率始终返回0的问题

你的问题出在HKSampleQuery是异步执行的:当你调用healthStore?.execute(query)后,函数会立刻执行return latestHeartRateBPM,这时候查询的回调块还没开始运行,latestHeartRateBPM还是初始值0。等HealthKit真正返回心率数据、修改变量值的时候,函数早就已经返回了,所以永远拿不到正确的心率值。

要解决这个问题,你需要用**闭包(Completion Handler)**来处理异步结果,因为同步返回的方式在这里不适用。修改后的代码如下:

func getLatestHeartRate(completion: @escaping (Int?) -> Void) {
    guard let sampleType = HKObjectType.quantityType(forIdentifier: .heartRate) else {
        completion(nil)
        return
    }
    
    let startDate = Calendar.current.date(byAdding: .month, value: -1, to: Date())
    let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictEndDate)
    let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
    
    // 把limit设为1,只取最新的一条数据,没必要查所有
    let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 1, sortDescriptors: [sortDescriptor]) { (_, result, error) in
        guard error == nil, let samples = result, let latestSample = samples.first as? HKQuantitySample else {
            completion(nil)
            return
        }
        
        // 处理心率单位:优先尝试count/min,再用count/s转换
        let bpmUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
        if latestSample.quantity.is(compatibleWith: bpmUnit) {
            let bpm = latestSample.quantity.doubleValue(for: bpmUnit)
            completion(Int(ceil(bpm)))
        } else {
            let bpsUnit = HKUnit.count().unitDivided(by: HKUnit.second())
            let bps = latestSample.quantity.doubleValue(for: bpsUnit)
            completion(Int(ceil(bps * 60)))
        }
    }
    
    healthStore?.execute(query)
}

使用方式:

getLatestHeartRate { heartRate in
    if let rate = heartRate {
        print("最新心率:\(rate) BPM")
        // 在这里处理心率值,比如更新UI
    } else {
        print("获取心率失败")
    }
}

额外注意点:

  • 把查询的limit设为1,只获取最新的一条数据,比查所有数据更高效
  • 避免强制解包result![0],改用安全的可选绑定,防止崩溃
  • 心率数据的单位可能是count/min或count/s,需要兼容两种情况
  • 确保已经向用户请求了HKObjectType.heartRate的读取权限

内容的提问来源于stack exchange,提问作者Niels Langerak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:39:35