HealthKit 后台交付在一分钟内运行多次

Posted

技术标签:

【中文标题】HealthKit 后台交付在一分钟内运行多次【英文标题】:HealthKit background delivery running many times in a minute 【发布时间】:2017-03-27 06:03:21 【问题描述】:

我已在我的委托的 didFinishLaunching 方法中注册了四种类型的 HealthKit 数据的后台传输。数据类型有步数、睡眠、锻炼和energyConsumed

我注意到在某些情况下,HealthKit/ios 每秒多次调用我对这些数据类型的观察者查询。以下是调用睡眠观察器查询的一些设备日志的示例:

2017/03/27 07:21:58:821 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:58:894 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:58:936 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:58:973 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:58:993 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:000 代表 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:024 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:130 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:145 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:156 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:169 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:309 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:328 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:346 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:404 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:480 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:499 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:520 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:547 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:561 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:571 委托 - 步骤观察者查询收到新数据

2017/03/27 07:21:59:583 委托 - 步骤观察者查询收到新数据

这是我的应用程序委托中创建此日志的代码:

- (void)setUpStepsObserverQuery 

__weak typeof(self) weakSelf = self;

HKSampleType *sampleType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKObserverQuery *query = [[HKObserverQuery alloc] initWithSampleType:sampleType predicate:nil updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error) 

    if (completionHandler) 
        completionHandler();
    
           
    if (error) 
        DDLogDebug(@"App Delegate - An error occured while setting up the stepCount observer: %@", error.localizedDescription);
    
     else 
        DDLogDebug(@"Delegate - steps observer query received new data");
        
        weakSelf.activityTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
            [weakSelf endBackgroundTask:weakSelf.activityTask];
        ];

// At this point I run an anchor query to check if there really is new data, and if there is I go ahead and send the new HealthKit data to our server.

    ];

    [_healthStore executeQuery:query]; // _healthStore is a shared instance of HKHealthStore I created earlier

这就是我为步骤数据启用后台传送的方式。我在didFinishLaunching 中调用了这个方法,它调用了我在上面共享一个sn-p 的方法setUpStepsObserverQuery

if ([defaults boolForKey:HK_ACTIVITY_SYNC]) 
    [self setUpStepsObserverQuery];
    [_healthStore enableBackgroundDeliveryForType:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]
                                        frequency:HKUpdateFrequencyImmediate
                                   withCompletion:^(BOOL success, NSError * _Nullable error) 
                                       DDLogDebug(@"Delegate - enabled step count background updates");
                                   ];

关于为什么 HealthKit 会在同一分钟内多次调用我的观察者查询的任何想法?

【问题讨论】:

【参考方案1】:

这是因为每次调用观察查询时,也会调用您的 didFinishLaunching 函数,并且还会调用 enableBackgroundDeliveryForType 并且每次启用它时,都会执行查询。

您必须检查是否启用了后台交付,不要再次启用它!

【讨论】:

我刚刚找到了这个帖子并且遇到了类似的问题。如何检查是否启用了后台交付?【参考方案2】:

这可能是一个错误而不是预期的行为,因此您应该使用Apple 提交雷达。

您也可以尝试指定频率较低的HKUpdateFrequency,例如HKUpdate​Frequency​Hourly。正如documentation 中提到的HKHealthStore 所述,该系统实际上旨在为高容量样本类型(例如步数和有功电能)提供每小时的最低频率。

【讨论】:

谢谢,我想我会尝试用一个小项目重现它并归档一个雷达。也许我读错了文档,但我认为他们说即使我立即要求步骤(例如),我也不会每小时收到超过一次的通知,无论如何。在其他情况下,我确实希望立即收到通知,因为对于睡眠之类的事情,除非我要求立即将数据发送给我,否则我不能指望在用户早上醒来后尽快收到通知。跨度> @BelleB.Cooper 为雷达收集有关此问题的最有用的信息是来自重现问题的设备的系统诊断 (adcdownload.apple.com/iOS/iOS_Logs/…)。我认为您正确理解了文档,但我只是建议一种解决方法,您现在可以尝试避免步骤问题。

以上是关于HealthKit 后台交付在一分钟内运行多次的主要内容,如果未能解决你的问题,请参考以下文章

在几秒钟内多次调用 Healthkit 后台交付

在几秒钟内多次调用 Healthkit 后台交付

HealthKit 后台交付

应用程序终止时的 Healthkit 后台交付

应用程序终止时的 Healthkit 后台交付

如何使用 HealthKit 后台交付?