HKAnchoredObjectQuery не возвращается надежно в фоновом режиме
Я пытаюсь заставить мое приложение синхронизировать данные HealthKit с нашей базой данных всякий раз, когда наблюдается новый ввод данных. Несмотря на некоторую двусмысленность в логике, я считаю, что мне удалось включить фоновую доставку для типов выборки и заставить наблюдателей реагировать при необходимости.
Однако в обработчике обновлений наблюдателя мне нужно создать HKAnchoredObjectQuery
для получения самых последних результатов из HealthKit, но эти запросы не возвращаются надежно, когда мое приложение работает в фоновом режиме. Часто, когда я добавляю точки выборки в HealthKit, привязанные запросы просто выполняются, но возвращаются только тогда, когда я возвращаю приложение на передний план.
В других случаях они возвращаются немедленно, без необходимости активировать приложение. Одной из возможных проблем является то, что все мои запросы наблюдателя запускают свои обработчики обновлений, создавая тем самым несколько AnchoredObjectQueries, которые могут возвращаться или не возвращаться. Я объяснил это далее в связанной ветке, потому что это может быть не связано.
Вот пример функции, которую я вызываю из обработчика обновлений HKObserverQuery:
func synchronizeRecentData(sampleType: HKSampleType, observerQuery: HKObserverQuery) {
let completionHandler: (HKAnchoredObjectQuery, [HKSample]?, Int, NSError?) -> Void = {
[unowned self] query, results, newAnchor, error in
if error != nil {
abort()
}
// Update queryAnchor
self.queryAnchors[sampleType] = newAnchor
guard let receivedNewSamples = results as? [HKQuantitySample] else {
abort()
}
// Handle received samples here
}
let query = HKAnchoredObjectQuery(type: sampleType,
predicate: nil,
anchor: self.queryAnchors[sampleType]!,
limit: HKObjectQueryNoLimit,
completionHandler: completionHandler)
healthKitStore.executeQuery(query)
}
2 ответа
Согласно документации HealthKit:
В отличие от запроса наблюдателя, эти обновления включают список элементов, которые были добавлены или удалены; однако привязанные объектные запросы не могут быть зарегистрированы для фоновой доставки. Для получения дополнительной информации см. HKAnchoredObjectQuery.
Единственный запрос, который может зарегистрироваться для фоновой доставки, - это HKObserverQuery
Я полагаю, что это потому, что когда ваше приложение просыпается в фоновом режиме, у вас есть очень ограниченное время для выполнения, прежде чем приложение снова будет приостановлено. Если вы используете UIBackgroundTaskIdentifier, вы должны быть в состоянии убедиться, что ваше приложение работает достаточно долго, чтобы завершить получение результатов HKAnchoredObjectQuery.