HealthKit(iOS)无法在后台(objC)提供数据

时间:2014-12-21 20:22:16

标签: ios iphone xcode health-kit hkhealthstore

我们目前正在尝试让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];
}

2 个答案:

答案 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;
}

HKObserverQuery Reference