HealthKit(iOS)不会在后台提供数据(objC) [英] HealthKit (iOS) won't deliver data in background (objC)

查看:138
本文介绍了HealthKit(iOS)不会在后台提供数据(objC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们目前正在尝试让HealthKit在后台运行,以便在应用关闭时向我们的服务器提供步骤数据。

We're currently trying to get HealthKit to work in the background, in order to deliver steps data to our server when the App is closed.

用于实验目的我们在XCode中创建了一个全新的iOS项目,启用了HealhtKit和Compabilities中的所有后台模式。在那之后,我们几乎运行代码(参见下面的内容)。

For experimental purposes we've created a brand new iOS project in XCode, enabled HealhtKit and all background modes in Compabilities. After that, we pretty much run the code (see further down).

首先发生的事情是应用程序要求我们授予的权限。我们期待的是应用程序应该每小时向服务器提供步骤数据。但它没有这样做,似乎应用程序在它不活动时无法做任何事情。

So what happens first is that the app ofcourse asks for the permissions, which we grant. What we're expecting is that the app should keep deliver the steps data every hour, to the server. But it doesnt do that, it seems like the app cant do anything when it's not active.

该应用程序仅在恢复或启动时提供数据,但根本不提供从后台(软关闭/硬关闭)

The app only deliver data when it gets resumed or started, but not at all from the background (Soft-closed / Hard-closed)

appdelegate.m:

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 出现问题,特别是此行:

I see something that might be causing an issue in your AppDelegate, particularly this line:

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

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

This is creating an NSURLConnection, but not starting it. Try changing it to this:

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

编辑:再看一下文档后

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

They recommend setting up your observer queries in your application didFinishLaunchingWithOptions: method. In your code above, you set the HKObserverQuery up in the authorization handler, which is called on a random background queue. Try making this change to set it up on the main thread:

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

HKObserverQuery Reference

这篇关于HealthKit(iOS)不会在后台提供数据(objC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆