仅限iOS Apple HealthKit Apple Watch步骤数据

时间:2017-09-06 05:46:11

标签: ios swift apple-watch health-kit

是否有办法从HealthKit数据库中获取Apple Watch步骤数据。我已经完成了Swift 3中的示例,并且有工作代码来获取Apple提供的合并数据,但包含来自iPhone和Apple Watch的步骤数据。

我没有看到任何人能够分开这两个数据的例子。我看到的每个例子都只给出合并的步骤数据。我可以迭代步骤数据源但不能使用源标识符来获取特定日历时间段的步骤数据。

我见过的所有Swift 3代码都遵循以下几行(Objective-C代码遵循类似的功能):

    // Request the step count.
    let stepType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)

    //let predicate = HKQuery.predicateForObjects(from: watchsource)
    let predicate = HKQuery.predicateForSamples(withStart: startdate, end: enddate, options: [])

    // Order doesn't matter, as we are receiving a quantity.

    let sortDescriptor = NSSortDescriptor(key:HKSampleSortIdentifierEndDate, ascending:false)

    // Fetch the steps.
    let query = HKSampleQuery(sampleType:stepType!, predicate: predicate, limit: 0, sortDescriptors:[sortDescriptor]) { query, results, error in
        var steps: Double = 0

        if results != nil {
            if results!.count > 0
            {
                for result in results as! [HKQuantitySample]
                {
                    steps += result.quantity.doubleValue(for: HKUnit.count())
                }
            } // if results
        } // if results != nil

        completion(steps, error as NSError?)
    } // HKSampleQuery()

    healthKitStore.execute(query)

上述代码作为正确的HealthKit身份验证的一部分工作正常,我可以获取任何时间段的步骤数据。

但是,HKSampleQuery()或其他派生的HealthKit库调用似乎无法用于特定来源,即Apple Watch数据,而无需Apple Watch本身的应用程序来阅读步骤数据。

是的,我知道可以读取iPhone计步器数据,然后从总步数中减去,但计步器数据仅保留七天,如果时间段是一个月,则没有太大用处。

有没有人解决过这个问题?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。我想为iPhone和Apple Watch分别设置步数。

这是我实现这一目标的方式。

首先,我们需要设备的谓词才能仅获得Apple Watch结果。

let watchPredicate = HKQuery.predicateForObjects(withDeviceProperty: HKDevicePropertyKeyModel, allowedValues: ["Watch"])

现在我们可以使用该谓词查询样本,我们将只获取Apple Watch条目。

我们还可以使用NSCompoundPredicate

为查询添加更多谓词。

答案 1 :(得分:1)

另一种方法是获取所有样本,然后按数据源(即 iPhone、Apple Watch 和第三方应用)对步数值进行分组。

private lazy var store = HKHealthStore()

private func queryStepsCont(startDate: Date,
                            endDate: Date,
                            result: @escaping (Result<[(source: String, count: Int)], Error>) -> Void) {
    guard let type = HKObjectType.quantityType(forIdentifier: .stepCount) else {
        result(.failure(IntegrationsServiceError.preconditionFail))
        return
    }
    let datePredicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate)

    let filteredByDateStepsCountQuery = HKSampleQuery(sampleType: type,
                                                      predicate: datePredicate,
                                                      limit: Int(HKObjectQueryNoLimit),
                                                      sortDescriptors: []) { _, samples, error in
        if let error = error {
            result(.failure(error))
            return
        }
        let sourceNameStepsCount = Dictionary(grouping: samples ?? []) { sample in
            sample.sourceRevision.source.name
        }.map { sourceNameSamples -> (String, Int) in
            let (sourceName, sourceSamples) = sourceNameSamples
            let stepsCount = sourceSamples
                .compactMap { ($0 as? HKQuantitySample)?.quantity.doubleValue(for: .count()) }
                .reduce(0, +)
            return (sourceName, Int(stepsCount))
        }
        result(.success(sourceNameStepsCount))
    }
    store.execute(filteredByDateStepsCountQuery)
}