简体   繁体   English

仅限 iOS Apple HealthKit Apple Watch 步数数据

[英]iOS Apple HealthKit Apple Watch step data only

Is there a way to get only Apple Watch step data from the HealthKit database.有没有办法只从 HealthKit 数据库中获取 Apple Watch 步骤数据。 I have worked through examples in Swift 3 and have working code to obtain the merged data which Apple supplies but that contains step data from both the iPhone and Apple Watch.我已经完成了 Swift 3 中的示例,并且有工作代码来获取 Apple 提供的合并数据,但其中包含来自 iPhone 和 Apple Watch 的步骤数据。

I have not seen any examples where anyone was able to separate the two pieces of data.我还没有看到任何人能够将两段数据分开的例子。 Every example I have seen only gives the merged step data.我见过的每个例子都只给出了合并的步骤数据。 I can iterate over the step data sources but cannot use the source identifier to obtain the step data for a specific calendar time period.我可以遍历步骤数据源,但不能使用源标识符来获取特定日历时间段的步骤数据。

All the Swift 3 code I have seen is along the following lines (Objective-C code follows similar functionality):我看到的所有 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)

The above code as part of a proper HealthKit authentication works fine and I am able to obtain the step data for any time period.上面的代码作为正确 HealthKit 身份验证的一部分工作正常,我能够获取任何时间段的步骤数据。

However, there seems to be no way that HKSampleQuery() or another derivative HealthKit library call can be used for a particular source, ie, Apple Watch data only without the need for having an App on the Apple Watch itself to read the step data.但是,似乎无法将 HKSampleQuery() 或其他衍生的 HealthKit 库调用用于特定来源,即 Apple Watch 数据,而无需在 Apple Watch 本身上安装应用程序来读取步数数据。

Yes, I know that one could read the iPhone pedometer data and then subtract that from the total number of steps but pedometer data is kept for only seven days, which is not much use if the time period is say, a month.是的,我知道人们可以读取 iPhone 计步器数据,然后从总步数中减去它,但计步器数据仅保留 7 天,如果时间段是一个月,这没什么用。

Has anyone solved this?有没有人解决过这个问题?

I was having the same issue.我遇到了同样的问题。 I wanted to get a separate step count for iPhone and Apple watch.我想为 iPhone 和 Apple Watch 分别计算步数。

here is how I achieved this.这是我实现这一目标的方法。

first, we need a predicate for devices to get only the Apple watch results.首先,我们需要一个设备谓词来仅获取 Apple Watch 结果。

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

now we can query for samples with this predicate and we'll just get the Apple watch entries.现在我们可以使用这个谓词查询样本,我们将只获得 Apple Watch 条目。

we can also include more predicates to our query, using NSCompoundPredicate我们还可以使用NSCompoundPredicate在我们的查询中包含更多谓词

Another approach is to fetch all the samples and then group step count values by the data source ie iPhone, Apple Watch, and third-party apps.另一种方法是获取所有样本,然后按数据源(即 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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM