我正在构建一个应用程序,该应用程序应该使用HKObserverQuery
来侦听HealthKit
中关于新添加的心率数据的变化,但奇怪的是,当我使用断点和控制台日志进行调试并手动向HealthKit
添加新数据时,观察者的updateHandler
块并没有一致地启动。
以下是大部分代码:
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
块在我设置时和应用程序出现在前台时只触发一次。如果我将应用程序放在后台,转到健康应用程序并尝试添加新数据,则行为非常不一致。有趣的是,如果我从来没有像苹果文档建议的那样调用completionHandler
,那么这个块会正确地触发大约5-6次,如果我调用completionHandler
,那么它可能每5次尝试就工作一次。我计划使用HKAnchoredObjectQuery
来获取我尝试过的最后一个数据,当观察者激发时,它可以很好地工作,但我无法让观察者正常工作。
我是不是错过了什么?如能提供帮助,我们将不胜感激。
更新:出于测试目的,我已将数据类型更改为bloodGlucose
,并注意到updateHandler
每次都会正确触发,这让我认为我实现的代码是正确的,行为因数据类型而异,有人能证实这一点吗?
根据Apple文档(https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery#discussion):";某些数据类型(如步数(的最小频率为HKUpdateFrequency.hourly。此频率是透明强制执行的;。
因此,是的,它确实取决于频率和某些数据类型的数据类型,即使您将频率包括为立即数。话虽如此,我在触发HKObserver查询心率时遇到了一些问题,所以我不完全确定频率是否可靠(观察者任务可能会超时(。