监测HealthKit的心率 - > HKAnchoredObjectQuery仅在applicationDidBecomeActive(BUG或FEATURE?)之后调用

时间:2015-10-28 22:42:48

标签: ios ios9 health-kit hkhealthstore

我正在编写一个简单的应用程序,只要将新的健康状况值写入HealthKit,就可以从HealthKit监控心率(HKQuantityTypeIdentifierHeartRate)。

正如WWDC2015(会议203)所见,我使用 HKAnchoredObjectQuery ,它可以用于添加和删除对象。每当我启动应用程序时,我都会调用 HKQuery 来获取最新的对象,并且 executionQuery 可以正常工作!但即使样品在那里,我也没有得到新的样品,但是如果我将应用程序带到后台并再次到达前台,我将获得所有新的心率。这是一个BUG吗?或者我该如何监控心率而不将应用程序带到后面和前台?

以下是我正在使用的代码(所有内容都存储在AppDelegate中),我从 didFinishLaunchingWithOptions 调用[self requestAccessDataTypes];

[healthStore enableBackgroundDeliveryForType:sampleType frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error) {}];

HKQuery *query = [self createHeartRateStreamingQuery:datum];
    if (query) {
        [healthStore executeQuery:query];
    }
    else
    {
        NSLog(@"workout can not start");
    }
-(HKQuery*)createHeartRateStreamingQuery:(NSDate*)workoutStartDate
{
    NSLog(@"%@ - createHeartRateStreamingQuery", [self class]);

    if ([HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]) {
        HKQuantityType *quantityType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];

        HKAnchoredObjectQuery * heartRateQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType predicate:nil anchor:anchor limit:HKObjectQueryNoLimit resultsHandler:^(HKAnchoredObjectQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable sampleObjects, NSArray<HKDeletedObject *> * _Nullable deletedObjects, HKQueryAnchor * _Nullable newAnchor, NSError * _Nullable error) {

            if (!error) {
                anchor = newAnchor;
                [self updateHeartRate:sampleObjects];

            }

        }];
        heartRateQuery.updateHandler = ^void(HKAnchoredObjectQuery *query, NSArray<__kindof HKSample *> * __nullable addedObjects, NSArray<HKDeletedObject *> * __nullable deletedObjects, HKQueryAnchor * __nullable newAnchor, NSError * __nullable error)
        {
            if (!error) {
                anchor = newAnchor;
                [self updateHeartRate:addedObjects];

            }

        };
        return heartRateQuery;
    }
    return nil;
}

2 个答案:

答案 0 :(得分:1)

目前(iOS 9.1,WatchOS 2.0.1),无法通过iOS应用从HealthKit获取最新数据。在WWDC演示中可能是因为代码在WatchOS应用程序的ExtensionDelegate而不是在iOS应用程序上运行。有一个rdar错误报告here

要获取iOS上的最新数据,如果不创建WatchOS应用程序,则无法实现。使用WatchOS应用程序,您可以使用Workout SessionWatch Connectivity在每次更改时将心率数据发送到iOS应用。

当然,如果您的心率数据不是来自Apple Watch,这没有任何帮助。希望它能在即将发布的版本中修复。

答案 1 :(得分:1)

您缺少观察HealthKit变化的关键部分。它被称为HKObserverQuery

Docs

  

观察者查询在后台队列上设置长时间运行的任务。   此任务监视HealthKit存储,并在任何时候发出警报   匹配数据将保存到商店或从商店中删除。观察者查询   让您的应用响应其他应用和设备所做的更改。

<强>小结

您必须在HKAnchoredObjectQuery中将HKObserverQuery打包并启用后台投放,以便获得有关更新的通知。然后,只要发生这种情况,您就可以执行查询。

注1:HKObserverQuery的更新处理程序不会为您提供任何Apple Health数据样本。您仍然必须使用适当的锚点执行HKAnchoredObjectQuery以获取样本。

注意2:每次启动应用时都必须设置HKObserverQuery

有关详细信息,请查看我的回答here