Byte Byte - 3 months ago 18
Swift Question

Getting all steps of today but truncating manually added steps, from Health kit using swift

I am getting today steps from healthkit using below code.

func retrieveStepCount(completion: (stepRetrieved: Double) -> Void) {
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)

let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let newDate = cal.startOfDayForDate(NSDate())

let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None) // Our search predicate which will fetch all steps taken today
let interval: NSDateComponents = NSDateComponents()
interval.day = 1

let query = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: predicate, options: .CumulativeSum, anchorDate: newDate as NSDate, intervalComponents:interval as NSDateComponents)

query.initialResultsHandler = { query, results, error in

if error != nil {

print("Something went Wrong")
return
}
if let myResults = results{
myResults.enumerateStatisticsFromDate(newDate, toDate: NSDate()) {
statistics, stop in
if let quantity = statistics.sumQuantityForSource(HKSource.defaultSource()) {

let steps = quantity.doubleValueForUnit(HKUnit.countUnit())

print("Steps = \(Int(steps))")
completion(stepRetrieved: steps)
}
}
}
}
executeQuery(query)
}


Now lets say I have these steps in total

enter image description here

From which I have some steps which were auto detected by device. and some were added by some other application to heathkit.

enter image description here

I do want both of them and I m getting both of them but the problem comes when user some some manuall steps to the healthkit.

enter image description here

I do not want to get these manually added steps. So basically I want to get (5,793 - 2300) = 3493 steps.

How can I do that ? I have tried to get name of HKSource I do know that when user enter steps manually, name of the source is "Health" but how do I filter steps on this base ? Please guide me about this and what am I missing here ? Thanks in advance

Answer

This might not be the best solution, But I believe it will work. What you can do is get all the steps which were added manually using HKSampleQuery. here is an example.

 func todayManuallyAddedStepsSteps(completion: (Double, NSError?) -> () )
    {

    let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) // The type of data we are requesting

    let date = NSDate()
    let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    let newDate = cal.startOfDayForDate(date)
    let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None) // Our search predicate which will fetch all steps taken today

    // The actual HealthKit Query which will fetch all of the steps and add them up for us.

    let query = HKSampleQuery(sampleType: type!, predicate: predicate, limit: 0, sortDescriptors: nil) { query, results, error in
        var steps: Double = 0

        if results?.count > 0
        {
            for result in results as! [HKQuantitySample]
            {
                print("Steps \(result.quantity.doubleValueForUnit(HKUnit.countUnit()))")
                print()

                // checking and adding manually added steps
                if result.sourceRevision.source.name == "Health" {
                    // these are manually added steps
                    print(result.sourceRevision.source.name)
                    print("Steps \(result.quantity.doubleValueForUnit(HKUnit.countUnit()))")
                    steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
                }
                else{
                    // these are auto detected steps which we do not want from using HKSampleQuery
                }
            }
            print(steps)
        }
        completion(steps, error)
    }

    executeQuery(query)
}

and then get the today total steps using HKStatisticsCollectionQuery like below

func TodayTotalSteps(completion: (stepRetrieved: Double) -> Void) {

    let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) // The type of data we are requesting

    let calendar = NSCalendar.currentCalendar()
    let interval = NSDateComponents()
    interval.day = 1

    let anchorComponents = calendar.components([.Day , .Month , .Year], fromDate: NSDate())
    anchorComponents.hour = 0
    let anchorDate = calendar.dateFromComponents(anchorComponents)

    let stepsQuery = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: nil, options: .CumulativeSum, anchorDate: anchorDate!, intervalComponents: interval)

    stepsQuery.initialResultsHandler = {query, results, error in
        let endDate = NSDate()
        let startDate = calendar.dateByAddingUnit(.Day, value: 0, toDate: endDate, options: [])
        if let myResults = results{  myResults.enumerateStatisticsFromDate(startDate!, toDate: endDate) { statistics, stop in
            if let quantity = statistics.sumQuantity(){
                let date = statistics.startDate
                let steps = quantity.doubleValueForUnit(HKUnit.countUnit())
                print("\(date): steps = \(steps)")
                completion(stepRetrieved: steps)
            }
            }
        }
    }
    executeQuery(stepsQuery)
}

Now you can call these methods and subtract manually added steps like below

todayManuallyAddedSteps({ (steps , error) in
            if error != nil{
                print(error)
            }
            else{
                // truncating manuall steps
                TodayTotalSteps({ (stepRetrieved) in
                    // steps without manuall steps
                    print(Int(stepRetrieved - steps))

                })
            }
        })