В настоящее время мы пытаемся заставить HealthKit работать в фоновом режиме, чтобы доставлять данные о шагах на наш сервер, когда приложение закрыто.HealthKit (iOS) не передает данные в фоновом режиме (objC)
Для экспериментальных целей мы создали новый проект iOS в XCode, включили HealhtKit и все фоновые режимы в Compabilities. После этого мы в значительной степени запускаем код (см. Далее).
Так что сначала происходит то, что приложение thecourse запрашивает разрешения, которые мы предоставляем. Мы ожидаем, что приложение должно постоянно доставлять данные шагов каждый час на сервер. Но он этого не делает, кажется, что приложение не может ничего сделать, когда оно неактивно.
приложение только передавать данные, когда он получает возобновляется или начала, но вовсе не из фона (Soft-замкнутыми/Hard-закрыто)
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];
}
Я взял свой образец кода и модифицировать его так, что он дает мне местное уведомление, а не отправлять данные на сервер (так как у меня нет сервера). Он работает, но я сделал несколько других изменений, поэтому я не знаю, какие из них необходимы. Изменения, которые я сделал, - избавиться от всех dispatch_async в главной очереди. Установите предикат только для выполнения сегодняшних шагов (для получения всех шагов потребовалось много времени).Перемещенный вызов completeHandler() в конец 'resultsHandler' в' getQuantityResult' - так, что он вызывается, как только вся обработка завершена – Paulw11
Привет, Paulw11, спасибо за ваш ответ. Вы уверены, что получаете результаты в фоновом режиме, например, еще через 1 час? Мы получаем результаты, но только за 1-2 минуты, потом ничего. Как насчет тебя? – Oakleaf
Хм, это странно, мы можем заставить его работать в симуляторе, но не на физическом устройстве iPhone. У нас заканчиваются подсказки, кто-нибудь знает, что искать? Так как он работает в симуляторе. – Oakleaf