【问题标题】:How to query for samples from health kit that have an HKDevice如何从具有 HKDevice 的 Health Kit 中查询样本
【发布时间】:2018-06-21 19:27:10
【问题描述】:

我想从 HealthKit 查询样本,但为了防止数据不准确或被操纵,我不希望其他应用程序写入健康的样本。有谁知道我可以使用什么谓词来过滤掉所有应用程序中的数据或只允许来自设备的数据?提前致谢。

编辑:我意识到应用程序可以通过包含 HKDevice 将数据保存到健康。所以过滤掉没有设备的样本是行不通的。

【问题讨论】:

    标签: ios swift healthkit hkhealthstore hksamplequery


    【解决方案1】:

    如果您想要排除手动输入的数据,请参阅此答案:Ignore manual entries from Apple Health app as Data Source

    用户通过 Health 添加到 HealthKit 的样本将具有 HKMetadataKeyWasUserEntered 键。

    【讨论】:

    • 我确实想排除手动数据,谢谢,但这篇文章更多的是关于从应用程序中排除数据。例如,我希望能够忽略模拟心率的应用中的样本。
    • 您有模拟心率的应用的具体示例吗?除了手动输入之外,存储 HealthKit 中传感器未记录的数据的应用程序的目的是什么?如果您担心在某种竞争中作弊,没有什么可以阻止模拟数据的应用程序使用本地 HKDevice 获取数据。
    • 不,我没有任何示例,但在我自己的应用程序中,我只需一个 Double 即可将心率样本直接存储到健康中。我没有过多考虑这样的应用程序可能具有什么合法目的,但我可以想象一个对调试目的有用的应用程序。其实我很担心作弊,你说得对,模拟数据可能有本地的HKDevice。正如您从我编辑的答案中看到的那样,尽管我添加了对“com.apple.health”捆绑标识符的检查。我假设应用程序无法模拟苹果捆绑 ID,但如果我错了,请纠正我。
    【解决方案2】:

    我仍然愿意接受建议和替代解决方案,但这是我的解决方法,因为我无法弄清楚如何使用谓词来完成工作。

     let datePredicate = HKQuery.predicateForSamples(withStart:Date(), end: nil, options: [])
    
     let sampleQuery = HKAnchoredObjectQuery(type: sampleType,
                                                   predicate: predicate,
                                                   anchor: nil,
                                                   limit: Int(HKObjectQueryNoLimit)) { query,
                                                                                       samples,
                                                                                       deletedObjects,
                                                                                       anchor,
                                                                                       error in
            if let error = error {
                print("Error performing sample query: \(error.localizedDescription)")
                return
            }
    
            guard let samples = samples as? [HKQuantitySample] else { return }
    
            // this line filters out all samples that do not have a device
            let samplesFromDevices = samples.filter { 
                $0.device != nil && $0.sourceRevision.source.bundleIdentifier.hasPrefix("com.apple.health") 
            }
            doStuffWithMySamples(samplesFromDevices)
        }
    

    如您所见,我只是在数据通过后对其进行过滤,而不是事先进行过滤。

    编辑:似乎健康中列出的来源分为应用程序和实际设备。不是 100% 确定他们是如何做到这一点的,但似乎设备部分下的源都有一个以 com.apple.health 为前缀的包标识符。希望这行得通。

    【讨论】:

      【解决方案3】:

      您可以在查询中过滤掉苹果未存储的结果,而不是迭代所有结果。

      首先,您需要获取所需类型的所有来源。

      let query = HKSourceQuery(sampleType: type,
                                        samplePredicate: predicate) {
                                          query, sources, error in
                                          
                                          // error handling ...
                                          
                                          // create a list of your desired sources
                                          let desiredSources = sources?.filter { 
                                                !$0.bundleIdentifier.starts(with: "com.apple.health")
                                           }
                                          
                                          // now use that list as a predicate for your query
                                          let sourcePredicate = HKQuery.predicateForObjects(from: desiredSources!)
      
                                          // use this predicate to query for data
      
              }
              
      

      您还可以使用NSCompoundPredicate 组合其他谓词

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多