【问题标题】:Monitor heart rate from HealthKit --> HKAnchoredObjectQuery only called after applicationDidBecomeActive (BUG or FEATURE?)从 HealthKit 监控心率 --> HKAnchoredObjectQuery 仅在 applicationDidBecomeActive 之后调用(BUG 或 FEATURE?)
【发布时间】:2015-10-28 22:42:47
【问题描述】:

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

正如在 WWDC2015(第 203 届会议)上看到的,我正在使用一个 HKAnchoredObjectQuery,它应该适用于添加和删除对象。每当我启动应用程序时,我都会调用 HKQuery 来获取最新的对象,而 executingQuery 工作正常!!!但是即使样本在那里,我也没有得到新的样本,但是如果我将应用程序带到后台并再次回到前台,我将获得所有新的心率。这是一个错误吗?或者我应该怎么做才能在不将应用程序置于后台和前台的情况下监测心率?

这是我正在使用的代码(所有内容都存储在 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;
}

【问题讨论】:

    标签: ios ios9 healthkit hkhealthstore


    【解决方案1】:

    您错过了观察 HealthKit 变化的关键部分。它叫做HKObserverQuery

    Docs

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

    回顾

    您必须将您的HKAnchoredObjectQuery 包装在HKObserverQuery 中并启用后台传送,以便收到有关更新的通知。然后,您可以在发生这种情况时执行查询。

    注意 1:HKObserverQuery 的更新处理程序不会为您提供任何 Apple Health 数据样本。您仍然需要使用适当的锚来执行您的 HKAnchoredObjectQuery 才能获取样本。

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

    更多信息,请查看我的回答here

    【讨论】:

      【解决方案2】:

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

      要获取 iOS 上的最新数据,必须创建 WatchOS 应用。借助 WatchOS 应用,您可以使用 Workout SessionWatch Connectivity 在每次发生变化时将心率数据发送到 iOS 应用。

      当然,如果您的心率数据不是来自 Apple Watch,这也无济于事。希望它会在即将发布的版本中得到修复。

      【讨论】:

      • 感谢您的回答,但我正在使用将 HealthKit 数据从手表自动传输到父应用程序,正如我在请求中所写的那样,数据或多或少是实时传输的!每当我启动应用程序时,我都会调用 HKQuery 以获取最新对象并在父应用程序(例如 iPhone)上执行查询,这工作正常!!!但是即使样本在那里,我也没有得到新的样本,但是如果我将应用程序带到后台并再次回到前台,我将获得所有新的心率。
      • 关闭应用程序才能获取最新数据肯定不是很理想?我试图暗示这个问题,希望 Apple 能够在数据进入 iOS 上的 HealthKit 时获取数据,而无需像这样的解决方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      相关资源
      最近更新 更多