Мониторинг сердечного ритма из HealthKit -> HKAnchoredObjectQuery вызывается только после applicationDidBecomeActive (BUG или FEATURE?)
Я пишу простое приложение для мониторинга частоты сердечных сокращений (HKQuantityTypeIdentifierHeartRate) из HealthKit всякий раз, когда в HealthKit записывается новое значение показателя здоровья.
Как видно на WWDC2015 (сессия 203), я использую HKAnchoredObjectQuery, который должен работать для добавления и удаления объектов. Всякий раз, когда я запускаю приложение, я вызываю HKQuery для новейших объектов и выполняю Query, который отлично работает!!! Но я не получаю новых образцов, даже если они есть, но если я перенесу приложение на задний план и снова на передний план, я получу все новые частоты сердечных сокращений. Это ошибка? Или что мне делать, чтобы контролировать частоту сердечных сокращений, не выводя приложение на задний и передний план?
Вот код, который я использую (все хранится в AppDelegate), я звоню [self requestAccessDataTypes];
from didFinishLaunchingWithOptions:
[healthStore enableBackgroundDeliveryForType:sampleType frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error) {}];
HKQuery *query = [self createHeartRateStreamingQuery:datum];
if (query) {
[healthStore executeQuery:query];
}
else
{
NSLog(@"workout can not start");
}
-(HKQuery*)createHeartRateStreamingQuery:(NSDate*)workoutStartDate
{
NSLog(@"%@ - createHeartRateStreamingQuery", [self class]);
if ([HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]) {
HKQuantityType *quantityType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
HKAnchoredObjectQuery * heartRateQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType predicate:nil anchor:anchor limit:HKObjectQueryNoLimit resultsHandler:^(HKAnchoredObjectQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable sampleObjects, NSArray<HKDeletedObject *> * _Nullable deletedObjects, HKQueryAnchor * _Nullable newAnchor, NSError * _Nullable error) {
if (!error) {
anchor = newAnchor;
[self updateHeartRate:sampleObjects];
}
}];
heartRateQuery.updateHandler = ^void(HKAnchoredObjectQuery *query, NSArray<__kindof HKSample *> * __nullable addedObjects, NSArray<HKDeletedObject *> * __nullable deletedObjects, HKQueryAnchor * __nullable newAnchor, NSError * __nullable error)
{
if (!error) {
anchor = newAnchor;
[self updateHeartRate:addedObjects];
}
};
return heartRateQuery;
}
return nil;
}
2 ответа
В настоящее время (iOS 9.1, WatchOS 2.0.1) невозможно получить последние данные из HealthKit через приложение для iOS. Это стало возможным в демонстрации WWDC, потому что код выполнялся в ExtensionDelegate приложения WatchOS, а не в приложении iOS. Здесь находится отчет об ошибке rdar.
Получить последние данные о iOS невозможно без создания приложения WatchOS. С приложением WatchOS вы можете использовать Workout Session и Watch Connectivity для отправки данных о частоте сердечных сокращений в приложение iOS при каждом их изменении.
Конечно, это не поможет, если данные о вашем пульсе не поступают с Apple Watch. Надеюсь, это будет исправлено в следующем выпуске.
Вам не хватает важной части для наблюдения за изменениями в HealthKit. Это называется HKObserverQuery
,
Запросы наблюдателя устанавливают долгосрочную задачу в фоновой очереди. Эта задача отслеживает хранилище HealthKit и предупреждает вас о сохранении или удалении соответствующих данных из хранилища. Запросы наблюдателя позволяют вашему приложению реагировать на изменения, внесенные другими приложениями и устройствами.
Резюме:
Вы должны обернуть HKAnchoredObjectQuery
в HKObserverQuery
с фоновой доставкой, чтобы получать уведомления об обновлениях. Затем вы можете выполнить свой запрос, когда это произойдет.
Примечание 1: HKObserverQuery
обработчик обновлений НЕ предоставит вам образцы данных Apple Health. Вы все еще должны выполнить свой HKAnchoredObjectQuery
с надлежащим якорем, чтобы получить образцы.
Примечание 2: Вы должны настроить HKObserverQuery
каждый раз, когда ваше приложение запускается.
Для получения дополнительной информации, посмотрите на мой ответ здесь.