Какая логика в фоновой доставке 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,

Другие вопросы по тегам