HKMetadataKeyWasUserEntered 坏了吗?当健康应用程序中有数据时,我总是得到 nil

Is HKMetadataKeyWasUserEntered broken? I keep getting nil when there is data in the health app

我正在尝试从健康应用程序中获取数据。特别是用户未自行输入的数据。例如,我有一个 iPhone 6+ 记录我走的步数。还有一个选项可以手动添加数据;如果您手动添加数据,健康应用会将数据标记为 "user added"。

这就是让我感到困惑的地方。假设我添加了 22 步计数。当我使用带有谓词

的 HKStatisticsQuery 查询数据时
HKQuery.predicateForObjectsWithMetadataKey(HKMetadataKeyWasUserEntered, allowedValues: [true])

我得到了 22 步的正确结果,因为我将 allowedValues 设置为 true 并且我自己添加了它。但是,当我尝试将 allowedValues 设置为 false 时,我没有得到任何结果

HKQuery.predicateForObjectsWithMetadataKey(HKMetadataKeyWasUserEntered, allowedValues: [false])

我在健康应用程序中确实有步数数据,但没有返回任何结果。

检查以下可能的区域以修复它:

  1. 您是否已授权您的应用程序访问 HealthKit 中的步数数据?
  2. 如果您在未经 HealthKit 授权的情况下从您的应用程序中查询步数,那么 HealthKit 不会 return 任何例外,它只会 return 仅在以下情况下从您的应用程序输入的步数可用,否则 returns nil.
  3. 在查询健康数据之前,使用 HKHealthStore class.
  4. 提供的 authorizationStatusForType: 方法检查步数的授权状态

更新 1:

我对 wasUserEntered 键的观察是:

  1. 如果用户从 HEALTH 应用程序输入步数数据,相应的 HKQuantitySamplemetadata 字典连同 HKWasUserEntered 键自动存储为 TRUE
  2. 如果用户从 Apple 的 HEALTH 应用程序以外的其他地方输入步数数据,相应的 health/fitness 设备或​​我们的应用程序应发送 metadata 字典,键 HKWasUserEntered 以及值 [=46] =]TRUE/FALSE。否则,metadata 属性 将包含 nil 对象。 因此,Apple 不会对没有元数据的数据应用谓词(谓词包含元数据键)。

为了调试此元数据,请尝试打印您的 HKQuantitySampleObject.metadata

Apple 在元数据上的实现与 NSPredicate 的对比:

  1. 如果从 Health/fitness 台设备观察到健康数据,HealthKit 不会将 metadata 词典添加到相应的健康记录中。
  2. 如果是 Apple Health app 以外的 Health 应用程序,开发者应手动添加 metadata 字典来记录他的健康数据。
  3. 如果没有 metadata 特定的健康记录并且 NSPredicatemetadata 有约束,那么 HealthKit 完全省略验证此类记录。

最后,

  1. 建议使用

    • (instancetype)quantitySampleWithType:(HKQuantityType *)quantityType 数量:(HKQuantity *)数量 开始日期:(NSDate *)开始日期 结束日期:(NSDate *)结束日期 元数据:(NSDictionary *)元数据;

而不是

+ (instancetype)quantitySampleWithType:(HKQuantityType *)quantityType
                              quantity:(HKQuantity *)quantity
                             startDate:(NSDate *)startDate
                               endDate:(NSDate *)endDate;

添加元数据。

  1. 向 Apple 报告此错误,谓词(包含 metadata 键)应应用于所有数据,无论是否检查 metadata 是否存在。

已经有一段时间了,你现在可能已经解决了这个问题,但我认为值得在这里发帖,以防其他人遇到同样的问题。

就像 Bhanu 提到的那样,Apple 自己创建的数据似乎没有 HKWasUserEntered 条目作为其元数据的一部分。

但 Apple 从来没有声称在他们的文档中这样做,所以正确的查询应该是过滤掉 HKWasUserEntered == true if 设置了该键的项目,但也归还了所有其他没有关联元数据的东西。

想法是 metadataDictionary,如果键不存在,则类型 returns nil。所以存在三种可能的情况:

  • HKMetadataKeyWasUserEntered == nil
  • HKMetadataKeyWasUserEntered == false
  • HKMetadataKeyWasUserEntered == true

其中,您只想过滤掉最后一个,因为它明确告诉您输入的是数据,而不是用户。

这可以在 HKQuery 上使用 + predicateForObjectsWithMetadataKey:operatorType:value: 便捷方法来完成,如下所示:

HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyWasUserEntered, operatorType: .notEqualTo, value: true)

当然,您最初的问题是:"Is HKMetadataKeyWasUserEntered broken?"。而且我不相信这是因为,如前所述,Apple 从未声称为他们自己的价值观编写该密钥。 :)