HealthKit (iOS) не предоставляет данные в фоновом режиме (objC)
В настоящее время мы пытаемся заставить HealthKit работать в фоновом режиме, чтобы доставлять данные шагов на наш сервер, когда приложение закрыто.
Для экспериментальных целей мы создали новый проект iOS в XCode, включили HealhtKit и все фоновые режимы в Compabilities. После этого мы в значительной степени запускаем код (см. Далее).
Итак, что происходит первым, так это то, что приложение thecourse запрашивает разрешения, которые мы предоставляем. Мы ожидаем, что приложение должно постоянно доставлять данные шагов каждый час на сервер. Но он этого не делает, кажется, что приложение не может ничего делать, когда оно неактивно.
Приложение только доставляет данные, когда оно возобновляется или запускается, но вовсе не с фона (Soft-closed/Hard-closed)
appdelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setTypes];
return YES;
}
-(void) setTypes
{
self.healthStore = [[HKHealthStore alloc] init];
NSMutableSet* types = [[NSMutableSet alloc]init];
[types addObject:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]];
[self.healthStore requestAuthorizationToShareTypes: types
readTypes: types
completion:^(BOOL success, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self observeQuantityType];
[self enableBackgroundDeliveryForQuantityType];
});
}];
}
-(void)enableBackgroundDeliveryForQuantityType{
[self.healthStore enableBackgroundDeliveryForType: [HKQuantityType quantityTypeForIdentifier: HKQuantityTypeIdentifierStepCount] frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error) {
}];
}
-(void) observeQuantityType{
HKSampleType *quantityType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKObserverQuery *query =
[[HKObserverQuery alloc]
initWithSampleType:quantityType
predicate:nil
updateHandler:^(HKObserverQuery *query,
HKObserverQueryCompletionHandler completionHandler,
NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (completionHandler) completionHandler();
[self getQuantityResult];
});
}];
[self.healthStore executeQuery:query];
}
-(void) getQuantityResult{
NSInteger limit = 0;
NSPredicate* predicate = nil;
NSString *endKey = HKSampleSortIdentifierEndDate;
NSSortDescriptor *endDate = [NSSortDescriptor sortDescriptorWithKey: endKey ascending: NO];
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType: [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]
predicate: predicate
limit: limit
sortDescriptors: @[endDate]
resultsHandler:^(HKSampleQuery *query, NSArray* results, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
// sends the data using HTTP
[self sendData: [self resultAsNumber:results]];
});
}];
[self.healthStore executeQuery:query];
}
Ответы
Ответ 1
Я вижу что-то, что может вызвать проблему в вашем AppDelegate
, особенно в этой строке:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
Это создает NSURLConnection, но не запускает его. Попробуйте изменить его на это:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
Изменить: после второго взгляда на документы
Они рекомендуют настраивать ваши запросы наблюдателей в вашем методе application didFinishLaunchingWithOptions:
. В приведенном выше коде вы устанавливаете HKObserverQuery
вверх в обработчике авторизации, который вызывается в случайной фоновой очереди. Попробуйте сделать это изменение, чтобы настроить его на основной поток:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setTypes];
[self observeQuantityType];
return YES;
}
Справочник HKObserverQuery
Ответ 2
Я узнал об этом некоторое время назад, когда говорил с кем-то из Apple. По-видимому, вы не можете получить доступ к данным HK в фоновом режиме, если устройство заблокировано:
Примечание
Поскольку хранилище HealthKit зашифровано, ваше приложение не может читать данные из магазина, когда телефон заблокирован. Это означает, что ваше приложение не может иметь доступ к магазину, когда он запускается в фоновом режиме. Однако приложения могут записывать данные в магазин, даже если телефон заблокирован. Хранилище временно кэширует данные и сохраняет их на зашифрованный магазин, как только телефон разблокируется.
от:
https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Framework/