Какая логика в фоновой доставке HKObserverQuery?
Мне нужно, чтобы мое приложение синхронизировалось между HealthKit и нашей базой данных, пока оно работает в фоновом режиме. Я просто не могу обернуться вокруг логики, которая определяет, как и когда HKObserverQueries запускают свои updateHandlers. Мне нужны данные различных типов выборки, поэтому я предполагаю, что мне нужен запрос наблюдателя для каждого из них. Правильно?
Согласно Apple о функции enableBackgroundDeliveryForType, "HealthKit будит ваше приложение всякий раз, когда новые образцы указанного типа сохраняются в магазине". Но если я включаю фоновые доставки и выполняю запросы наблюдателей, скажем, на содержание глюкозы в крови и веса, они оба, похоже, запускают свои обработчики обновлений всякий раз, когда я вводю данные в один из них в приложении Health. Это также, кажется, происходит, даже когда я включаю фоновую доставку только для одного из типов образцов. Зачем?
func startObserving(completion: ((success: Bool) -> Void)!) {
let sampleTypeBloodGlucose = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBloodGlucose)!
let sampleTypeWeight = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)!
// Enable background delivery for blood glucose
self.healthKitStore.enableBackgroundDeliveryForType(sampleTypeBloodGlucose, frequency: .Immediate) {
(success, error) in
if error != nil {
abort()
}
}
// Enable background delivery for weight
self.healthKitStore.enableBackgroundDeliveryForType(sampleTypeWeight, frequency: .Immediate) {
(success, error) in
if error != nil {
abort()
}
}
// Define update handlers for background deliveries
let updateHandlerBloodGlucose: (HKObserverQuery, HKObserverQueryCompletionHandler, NSError?) -> Void = {
query, completionHandler, error in
if error != nil {
abort()
}
// Handle data and call the completionHandler
completionHandler()
}
let updateHandlerWeight: (HKObserverQuery, HKObserverQueryCompletionHandler, NSError?) -> Void = {
query, completionHandler, error in
if error != nil {
abort()
}
// Handle data and call the completionHandler
completionHandler()
}
let observerQueryBloodGlucose = HKObserverQuery(sampleType: sampleTypeBloodGlucose, predicate: nil, updateHandler: updateHandlerBloodGlucose)
healthKitStore.executeQuery(observerQueryBloodGlucose)
let observerQueryWeight = HKObserverQuery(sampleType: sampleTypeWeight, predicate: nil, updateHandler: updateHandlerWeight)
healthKitStore.executeQuery(observerQueryWeight)
completion(success: true)
}
1 ответ
Если вы используете функцию фоновой доставки HealthKit, то да, вам нужно открыть HKObserverQuery
для каждого типа данных, которые вы наблюдаете и обрабатывает вызовы updateHandler
и назовите предоставленное завершение, когда вы закончите. Тем не менее updateHandler
из HKObserverQuery
носит рекомендательный характер, и вызовы не обязательно соответствуют непосредственным изменениям в базе данных HealthKit (не всегда достаточно информации, чтобы определить, что ваше приложение обработало, а что нет, поэтому иногда обработчик может работать, когда нет новые данные).
Не беспокойтесь о понимании или контроле именно тогда, когда updateHandler
работает - просто используйте его как триггер для выполнения других запросов, которые на самом деле будут предоставлять вам обновленные значения из HealthKit. Если вам нужно точно знать, какие образцы в HealthKit являются новыми, например, то ваше приложение должно использовать HKAnchoredObjectQuery
,