How to get Apple health data by date wise?

杀马特。学长 韩版系。学妹 提交于 2020-01-03 07:24:09

问题


Apple health app gives the data by Date wise as shown in below image.

By using HealthKit i am fetching the steps data from apple health as

let p1 = HKQuery.predicateForSamples(withStart: fromDate, end: Date(), options: .strictStartDate)
let p2 = HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyWasUserEntered, operatorType: .notEqualTo, value: true)
let timeSortDesriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)//as in health kit entry
let quantityType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
let predicate = HKQuery.predicateForSamples(withStart: fromDate, end: Date(), options: .strictStartDate)
let sourceQuery = HKSourceQuery(sampleType: quantityType, samplePredicate: predicate, completionHandler: { query,sources,error in

if sources?.count != 0  && sources != nil {

                let lastIndex = sources!.count - 1
                var sourcesArray = Array(sources!)
                for i in 0..<sourcesArray.count {
                    let sourcePredicate = HKQuery.predicateForObjects(from: sourcesArray[i])
                    let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [p1, p2,sourcePredicate])
                    let query = HKSampleQuery(sampleType: quantityType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [timeSortDesriptor], resultsHandler: { query, results, error in
                        guard let samples = results as? [HKQuantitySample] else {
                            return
                        }......

sourceQuery gives multiple object like Apple watch, My iPhone. further i am using for loop with HKSampleQuery which gives HKQuantitySample object. Problem is [HKQuantitySample] gives Array of step data which is not sorted datewise. I am looking for data which are club for the date like what apple health show in Health app.

Yes there is workaround like manually sort the data from [HKQuantitySample] by date wise. but there may be workaround by using predicates or something else. Please feel free to ask if you need any extra information.

EDIT: As suggested by @Allan I have added HKStatisticsCollectionQuery, YES it gives data datewise but the steps count receiving is not same as in Apple health App. is something Addition/modification required in below code ?

let last10Day = Calendar.current.date(byAdding: .day, value: -10, to: Date())!
        var interval = DateComponents()
        interval.day = 1
        let quantityType1 = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
        // Create the query
        let query = HKStatisticsCollectionQuery(quantityType: quantityType1,
                                                quantitySamplePredicate: nil,
                                                options: .cumulativeSum,
                                                anchorDate: last10Day,
                                                intervalComponents: interval)
        // Set the results handler
        query.initialResultsHandler = {
            query, results, error in

            guard let statsCollection = results else {
                // Perform proper error handling here
                fatalError("*** An error occurred while calculating the statistics: \(String(describing: error?.localizedDescription)) ***")
            }
            let endDate = Date()
            statsCollection.enumerateStatistics(from: last10Day, to: endDate, with: { (statistics, stop) in
                if let quantity = statistics.sumQuantity() {
                    let date = statistics.startDate
                    let value = quantity.doubleValue(for: HKUnit.count())
                    print("--value-->",value, ",--For Date-->",date)
                }
            })
        }
            healthStore.execute(query)

回答1:


Use HKStatisticsCollectionQuery to fetch data from a certain period. Here is an example showing how to fetch steps for the last 30 days:

private let healthStore = HKHealthStore()
private let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!

func importStepsHistory() {
    let now = Date()
    let startDate = Calendar.current.date(byAdding: .day, value: -30, to: now)!

    var interval = DateComponents()
    interval.day = 1

    var anchorComponents = Calendar.current.dateComponents([.day, .month, .year], from: now)
    anchorComponents.hour = 0
    let anchorDate = Calendar.current.date(from: anchorComponents)!

    let query = HKStatisticsCollectionQuery(quantityType: stepsQuantityType,
                                        quantitySamplePredicate: nil,
                                        options: [.cumulativeSum],
                                        anchorDate: anchorDate,
                                        intervalComponents: interval)
    query.initialResultsHandler = { _, results, error in
        guard let results = results else {
            log.error("Error returned form resultHandler = \(String(describing: error?.localizedDescription))")
            return
    }

        results.enumerateStatistics(from: startDate, to: now) { statistics, _ in
            if let sum = statistics.sumQuantity() {
                let steps = sum.doubleValue(for: HKUnit.count())
                print("Amount of steps: \(steps), date: \(statistics.startDate)")
            }
        }
    }

    healthStore.execute(query)
}



回答2:


If you want totals for step count separated by day like in the Health app, you should use HKStatisticsCollectionQuery, not HKSampleQuery. The documentation provides example code for grouping results by week, but you can modify it group by day instead.



来源:https://stackoverflow.com/questions/50620547/how-to-get-apple-health-data-by-date-wise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!