HealthKit HKObserverQuery 没有持续触发

Posted

技术标签:

【中文标题】HealthKit HKObserverQuery 没有持续触发【英文标题】:HealthKit HKObserverQuery not firing consistently 【发布时间】:2020-10-28 08:50:40 【问题描述】:

我正在构建一个应用程序,该应用程序应该使用 HKObserverQuery 监听 HealthKit 中关于新添加的心率数据的变化,但奇怪的是,当我使用断点和控制台日志进行调试时,观察者的 updateHandler 块不会持续触发并将新数据手动添加到HealthKit

大部分代码如下:

import HealthKit

protocol HeartRateDataProviding 
    var delegate: HeartRateDataProviderDelegate?  get set 
    func startExecutingQuery(until: Date?)


protocol HeartRateDataProviderDelegate: class 
    func didQueryData(entry: HeartRateDataEntry)


struct HeartRateDataEntry 
    let date: Date
    let value: Int


class HeartRateDataProvider: HeartRateDataProviding 
    private let healthStore: HKHealthStore
    private let heartRateType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!
    private let heartRateUnit = HKUnit(from: "count/min")
    weak var delegate: HeartRateDataProviderDelegate?

    init(healthStore: HKHealthStore = .init()) 
        self.healthStore = healthStore
    

    func startExecutingQuery() 
        healthStore.enableBackgroundDelivery(for: heartRateType, frequency: .immediate)  success, error in
            print("Observer Query background delivery enabled -> successful: \(success) error: \(String(describing: error))")
        
        healthStore.execute(self.createObserverQuery())
    

    private func createObserverQuery() -> HKQuery 
        let query = HKObserverQuery(sampleType: heartRateType, predicate: nil)  query, completionHandler, error in
            print("Hello!")
            completionHandler()
        

        return query
    

    private func formatSamples(samples: [HKSample]?) 
        guard let samples = samples as? [HKQuantitySample],
              let sample = samples.last else  return 

        let entry = HeartRateDataEntry(date: sample.endDate,
                                       value: Int(sample.quantity.doubleValue(for: heartRateUnit)))
        delegate?.didQueryData(entry: entry)
    

我的AppDelegate 中有一个此类的实例,并在didFinishLaunchingWithOptions 上执行查询。

查询的updateHandler 块仅在我设置它和应用程序进入前台时触发一次,如果我将应用程序置于后台并转到健康应用程序并尝试添加新数据,则行为非常不一致。 有趣的是,如果我从未像 Apple 文档建议的那样调用 completionHandler,则该块会正确触发大约 5-6 次,如果我调用 completionHandler,那么它可能每 5 次尝试一次就有效。 我打算使用HKAnchoredObjectQuery 来获取我尝试过的最后一个数据,当观察者触发时它工作正常,但我无法让观察者正常工作。

我错过了什么吗?一些帮助将不胜感激。

更新:出于测试目的,我已将数据类型更改为 bloodGlucose,并注意到 updateHandler 每次都会正确触发,这让我认为我实现的代码是正确的,并且行为因数据类型而异,有人可以确认一下吗?

【问题讨论】:

【参考方案1】:

根据 Apple 文档 (https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery#discussion):“某些数据类型(例如步数)的最低频率为 HKUpdateFrequency.hourly。此频率是透明强制执行的”。

所以是的,它确实取决于频率和某些数据类型的数据类型,即使您将频率包括为立即数。话虽如此,我在触发 HKObserverQuery 以获取心率时遇到了一些问题,所以我不完全确定频率是否可靠(观察者任务可能会超时)。

【讨论】:

以上是关于HealthKit HKObserverQuery 没有持续触发的主要内容,如果未能解决你的问题,请参考以下文章

从 HKObserverQuery 获取结果

HKAnchoredObjectQuery 可以在 HealthKit 中查询已删除的 HKSampleType 吗?

HKAnchoredObjectQuery 可以在 HealthKit 中查询已删除的 HKSampleType 吗?

将 HKSample 与另一个 HKSample 进行比较以防止重复

将 HKSample 与另一个 HKSample 进行比较以防止重复

HKObserverQuery 无法在 iPhone 上运行