HealthKit(iOS)不会在后台传递数据(objC)

我们目前正在尝试让HealthKit在后台工作,以便在应用程序closures时将步骤数据传递到我们的服务器。

为了实验目的,我们在XCode中创build了一个全新的iOS项目,启用了HealhtKit和兼容性中的所有背景模式。 之后,我们几乎可以运行代码(详见下文)。

那么首先会发生的事情是,应用程序要求我们授予的权限。 我们期望的是,应用程序应该每隔一小时向服务器传送步骤数据。 但它不这样做,似乎应用程序无法做任何事情,当它不活跃。

应用程序只能在恢复或启动时传递数据,但完全不会从背景(软closures/硬closures)

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]; } 

我在你的AppDelegate发现了一些可能导致问题的东西,特别是这一行:

 [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

这是创build一个NSURLConnection,但不启动它。 尝试将其更改为:

 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start]; 

编辑:在第二次看文档之后

他们build议在application didFinishLaunchingWithOptions:方法中设置观察者查询。 在上面的代码中,您将HKObserverQuery设置在授权处理程序中,在随机后台队列中调用该授权处理程序。 尝试将此更改设置在主线程上:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self setTypes]; [self observeQuantityType]; return YES; } 

HKObserverQuery参考

我刚才在与苹果的人交谈时发现了这一点。 如果设备被locking,显然你不能在后台访问香港数据:

注意

由于HealthKit商店已encryption,因此手机locking时,应用程序无法从商店读取数据。 这意味着您的应用在后台启动时可能无法访问商店。 但是,应用程序仍然可以将数据写入商店,即使手机已locking。 一旦手机解锁,商店就暂时caching数据并将其保存到encryption存储区。

来自: https : //developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Framework/