2014-12-21 26 views
14

我们目前正在试图让HealthKit在后台运行数据,以提供数据的步骤到我们的服务器时,应用程序被关闭。HealthKit(IOS)不会提供后台(objC)

对于实验目的,我们已经创建了一个全新的iOS项目在Xcode中,启用HealhtKit和Compabilities所有背景模式。之后,我们几乎可以运行代码(详见下文)。

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

的应用程序,只有当它被恢复或启动,但不是在所有从背景(软关闭/硬关闭)提供的数据

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

我把你的示例代码和修改它,这样它给了我一个本地通知,而不是将数据发送到服务器(因为我没有服务器)。它正在工作,但我做了其他一些更改,所以我不知道哪一个是必需的。我所做的更改是 - 摆脱主队列上的所有dispatch_async。设置谓词只提供今天的步骤(检索所有步骤需要很长时间)。移动到'resultsHandler'结束调用completionHandler()在'getQuantityResult' - 所以它被调用一次全部处理完成 – Paulw11

+0

嗨Paulw11,感谢您的回复。你确定你在后台得到结果,例如1小时后?我们得到的结果,但只有1-2分钟,然后没有。你呢? – Oakleaf

+0

嗯,这很奇怪,我们可以让它在模拟器中工作,但不在物理iPhone设备上。我们没有线索,有谁知道要寻找什么?由于它在模拟器中工作.. – Oakleaf

回答

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

5

我说话的苹果一个人的时候,而前发现了这件事一点。显然,你不能在后台访问香港的数据,如果该设备被锁定:

注意

因为HealthKit店进行加密,应用程序不能从商店当手机处于锁定状态读取数据 。这意味着您的应用可能不会在后台启动时访问商店 。 但是,应用程序仍可以将数据写入到存储,即使在手机 被锁定。这家商店暂时缓存数据,并将其尽快手机被解锁保存到 加密存储。

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