iOS Apple HealthKit Apple Watch только данные шага

Есть ли способ получить только данные шагов Apple Watch из базы данных HealthKit. Я работал с примерами в 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 ответа

У меня была такая же проблема. Я хотел получить отдельный счет шагов для iPhone и Apple Watch.

вот как я этого добился.

Во-первых, нам нужен предикат, чтобы устройства получали только результаты Apple Watch.

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

теперь мы можем запросить образцы с этим предикатом, и мы просто получим записи Apple Watch.

мы также можем включить больше предикатов в наш запрос, используя NSCompoundPredicate

Другой подход - получить все образцы, а затем сгруппировать значения счетчика шагов по источнику данных, то есть 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)
}
Другие вопросы по тегам