HealthKit HKObserverQuery не срабатывает постоянно

Я создаю приложение, которое должно отслеживать изменения в HealthKit относительно недавно добавленных данных о частоте пульса с помощью HKObserverQuery но, как ни странно, наблюдатель 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блокировка срабатывает только один раз, когда я его настраиваю и когда приложение переходит на передний план. Если я переведу приложение в фоновый режим, перейду в приложение "Здоровье" и попытаюсь добавить новые данные, поведение будет очень непоследовательным. Интересно, что блок срабатывает правильно примерно 5-6 раз, если я никогда не вызываю completionHandler как это предлагают документы Apple, если я позвоню completionHandlerтогда это срабатывает, может быть, один раз из каждых 5 попыток. Я планирую использовать HKAnchoredObjectQuery чтобы получить последние данные, которые я пробовал, и он отлично работает, когда наблюдатель запускается, но я не могу заставить наблюдателя работать должным образом.

Я что-то упускаю? Некоторая помощь будет принята с благодарностью.

Обновление: я изменил тип данных на bloodGlucose в целях тестирования и заметил, что updateHandler срабатывает правильно каждый раз, это наводит меня на мысль, что реализованный мной код правильный, а поведение зависит от типа данных. Может ли кто-нибудь подтвердить это?

1 ответ

Согласно документации Apple (https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery#discussion): «Некоторые типы данных, например количество шагов, имеют минимальную частоту HKUpdateFrequency.hourly. применяется прозрачно ".

Так что да, это действительно зависит от типа данных для частоты и для некоторых типов данных, даже если вы включили частоту как немедленную. При этом у меня были некоторые проблемы с запуском HKObserverQuery для измерения частоты пульса, поэтому я не совсем уверен, надежна ли частота (возможно, есть тайм-аут для задач наблюдателя).

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