Запрос HealthKit для плавательных гребков / стиля на круг

#ios #healthkit #watchos

#iOS #healthkit #watchos

Вопрос:

Мне удалось запросить плавательные удары, но это всего лишь совокупная сумма.

 private func querySwimStrokeCount(for sample: HKSample) {
    let strokeCount = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.swimmingStrokeCount)!
    let sampleDate = HKQuery.predicateForSamples(withStart: sample.startDate, end: sample.endDate, options: [])
    
    let query = HKStatisticsQuery(quantityType: strokeCount,
                                  quantitySamplePredicate: sampleDate,
                                  options: .cumulativeSum) { (query, statisticsOrNil, errorOrNil) in
        
        guard let statistics = statisticsOrNil else {
            return
        }
        
        let sum = statistics.sumQuantity()
        let strokeCount = sum?.doubleValue(for: HKUnit.count()) ?? 0
        
        DispatchQueue.main.async {
            self.strokeCount = Int(strokeCount)
        }
    }
    
    HKHealthStore().execute(query)
}
  

Теперь я пришел к вопросу, как мне получить количество ударов за круг и стиль плавания для этого круга? Приложение Apple Health показывает эти данные (см. Скриншоты), но я понятия не имею, как их запрашивать.

Любая помощь приветствуется!

Приложение для здоровья Плавательные гребки на круг

Приложение для здоровья Стиль плавания для гребков

Ответ №1:

вы используете HKStatisticsQuery which только для получения агрегированных данных.

Запросы статистики вычисляют общую статистику по набору совпадающих выборок. Вы можете использовать статистические запросы для вычисления минимального, максимального или среднего значения набора дискретных величин или использовать их для вычисления суммы для совокупных величин.

Чтобы получить реальные образцы HKSampleQuery

Вы можете использовать примеры запросов для поиска любых конкретных подклассов класса HKSample, включая объекты HKCategorySample, HKCorrelation, HKQuantitySample и HKWorkout. Образец запроса возвращает образцы объектов, которые соответствуют предоставленному типу и предикату. Вы можете указать порядок сортировки для возвращаемых образцов или ограничить количество возвращаемых образцов. Другие классы запросов могут использоваться для выполнения более специализированных поисков и вычислений. Для получения дополнительной информации см. HKQuery.

или HKAnchoredObjectQuery который я предпочитаю отслеживать все изменения

Привязанные объектные запросы предоставляют простой способ поиска новых данных в хранилище HealthKit. Запрос hkanchoredobject возвращает значение привязки, которое соответствует последнему образцу или удаленному объекту, полученному этим запросом. Последующие запросы могут использовать эту привязку, чтобы ограничить свои результаты только новыми сохраненными или удаленными объектами. Запросы привязанных объектов в основном неизменяемы. Вы можете назначить свойство updateHandler запроса после создания экземпляра объекта, но вы должны установить все остальные свойства при создании экземпляра объекта. Вы не можете их изменить.

И вот, надеюсь, полезный код для вашей проблемы

 var anchor = self.getAnchorFor() // My private method to get the latest anchor for a type of HKEntry
let sampleType = HKObjectType

self.anchoredQuery = HKAnchoredObjectQuery(type: sampleType, predicate: nil, anchor: anchor, limit: HKObjectQueryNoLimit) { (query, samplesOrNil, deletedObjectsOrNil, newAnchor, errorOrNil) in
    
    guard let addedObjects = samplesOrNil, let deletedObjects = deletedObjectsOrNil else {
        // Handle the error here.
        return;
    }
    
    anchor = newAnchor
    self.storeNewAnchor() // My private method to store the latest anchor for a type of HKEntry
    
    for obj in addedObjects {
        if let sampleObj = obj as? HKWorkout{ // HKWorkout is just an example for a typ
            let uuid = sampleObj.uuid.uuidString
            let source = sampleObj.sourceRevision.source.name
            let sourceBundleID = sampleObj.sourceRevision.source.bundleIdentifier
            
            print("object added: "   uuid)
            print("source: "   source   " bundleID: "   sourceBundleID)
        }
    }
    
    for obj in deletedObjects {
        let uuid = obj.uuid.uuidString
        
        print("object deleted: "   uuid)

    }
    
    print("Finished-")
}


// Optionally, add an update handler.
self.anchoredQuery!.updateHandler = { (query, samplesOrNil, deletedObjectsOrNil, newAnchor, errorOrNil) in
    
    guard let addedObjects = samplesOrNil, let deletedObjects = deletedObjectsOrNil else {
        // Handle the error here.
        

        return;
    }
    
    anchor = newAnchor
    self.storeNewAnchor() // My private method to store the latest anchor for a type of HKEntry
    
    for obj in addedObjects {
        if let sampleObj = obj as? HKWorkout{ // HKWorkout is just an example for a typ
            let uuid = sampleObj.uuid.uuidString
            let source = sampleObj.sourceRevision.source.name
            let sourceBundleID = sampleObj.sourceRevision.source.bundleIdentifier

            print("object added: "   uuid)
            print("source: "   source   " bundleID: "   sourceBundleID)

        }
    }
    
    for obj in deletedObjects {
        let uuid = obj.uuid.uuidString
        
        print("object deleted: "   uuid)

    }
    
    print("Update Finished-")
}

// Run the query.
self.healthStore.execute(self.anchoredQuery!)
  

Комментарии:

1. Хорошо, я понял идею, но ваш код на самом деле не помогает. Я думаю, что мне нужен запрос HKSampleQuery, но я все еще не могу найти количество ударов на круг

2. Спасибо, я дал вам награду за то, что указали мне правильное направление. Однако, возможно, вам следует удалить свой код, потому что он не связан с вопросом.

Ответ №2:

ответ @incmiko указал мне правильное направление, посмотрев на HKSampleQuery . Однако его / ее код мне не помог. Итак, вот что я сделал, чтобы получить стиль гребка на круг.

 private func querySwimStrokes(for sample: HKSample) {
    let sampleType = HKSampleType.quantityType(forIdentifier: .swimmingStrokeCount)!
    let sampleDate = HKQuery.predicateForSamples(withStart: sample.startDate, end: sample.endDate, options: [])
    let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
    
    let query = HKSampleQuery(sampleType: sampleType,
                              predicate: sampleDate,
                              limit: HKObjectQueryNoLimit,
                              sortDescriptors: [sortDescriptor]) { query, samplesOrNil, errorOrNil in
        
        samplesOrNil?.forEach({ sample in
                            
            if let quantitySample = sample as? HKQuantitySample {
                let strokes = quantitySample.quantity.doubleValue(for: HKUnit.count())
                print(strokes)
            }
            
            if let strokeStyleInt = sample.metadata?["HKSwimmingStrokeStyle"] as? Int,
               let strokeStyle = HKSwimmingStrokeStyle(rawValue: strokeStyleInt){
                print(strokeStyle)
            }
        })
    }
    
    HKHealthStore().execute(query)
}