我们目前正在尝试让HealthKit在后台运行,以便在App关闭时向我们的服务器提供步骤数据。
出于实验目的,我们在XCode中创建了一个全新的iOS项目,启用了HealhtKit以及Compabilities中的所有后台模式。在那之后,我们几乎运行代码(见下文)。
首先发生的事情是应用程序要求我们授予的权限。我们期待的是应用程序应该每小时向服务器提供步骤数据。但它并没有这样做,似乎应用程序在它不活动时无法做任何事情。
应用程序仅在恢复或启动时提供数据,但在后台完全没有数据(软关闭/硬关闭)
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];
}
答案 0 :(得分:5)
我不久前在与Apple的某个人交谈时发现了这一点。显然,如果设备被锁定,您无法在后台访问HK数据:
请注意
由于HealthKit商店已加密,因此您的应用无法读取数据 手机锁定时从商店出来。这意味着您的应用可能不会 能够在后台启动时访问商店。 但是,即使在手机上,应用仍然可以将数据写入商店 锁住了。商店暂时缓存数据并将其保存到 电话解锁后立即加密存储。
自: https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Framework/
答案 1 :(得分:0)
我在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;
}