HealthKit Swift getting today's steps
HKStatisticsCollectionQuery is better suited to use when you want to retrieve data over a time span. Use HKStatisticsQuery to just get the steps for a specific date.
Swift 5:
let healthStore = HKHealthStore()func getTodaysSteps(completion: @escaping (Double) -> Void) { let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)! let now = Date() let startOfDay = Calendar.current.startOfDay(for: now) let predicate = HKQuery.predicateForSamples( withStart: startOfDay, end: now, options: .strictStartDate ) let query = HKStatisticsQuery( quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum ) { _, result, _ in guard let result = result, let sum = result.sumQuantity() else { completion(0.0) return } completion(sum.doubleValue(for: HKUnit.count())) } healthStore.execute(query)}
Here is the right way using HKStatisticsCollectionQuery courtesy of the direction from the code above.
This is written in Swift 3 so you may have to convert some of the code back to 2.3 or 2 if not on 3 yet.
Swift 3
func retrieveStepCount(completion: (stepRetrieved: Double) -> Void) { // Define the Step Quantity Type let stepsCount = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount) // Get the start of the day let date = Date() let cal = Calendar(identifier: Calendar.Identifier.gregorian) let newDate = cal.startOfDay(for: date) // Set the Predicates & Interval let predicate = HKQuery.predicateForSamples(withStart: newDate, end: Date(), options: .strictStartDate) var interval = DateComponents() interval.day = 1 // Perform the Query let query = HKStatisticsCollectionQuery(quantityType: stepsCount!, quantitySamplePredicate: predicate, options: [.cumulativeSum], anchorDate: newDate as Date, intervalComponents:interval) query.initialResultsHandler = { query, results, error in if error != nil { // Something went Wrong return } if let myResults = results{ myResults.enumerateStatistics(from: self.yesterday, to: self.today) { statistics, stop in if let quantity = statistics.sumQuantity() { let steps = quantity.doubleValue(for: HKUnit.count()) print("Steps = \(steps)") completion(stepRetrieved: steps) } } } } storage.execute(query) }
Objective-C
HKQuantityType *type = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];NSDate *today = [NSDate date];NSDate *startOfDay = [[NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian] startOfDayForDate:today];NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startOfDay endDate:today options:HKQueryOptionStrictStartDate];NSDateComponents *interval = [[NSDateComponents alloc] init];interval.day = 1;HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:type quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum anchorDate:startOfDay intervalComponents:interval];query.initialResultsHandler = ^(HKStatisticsCollectionQuery * _Nonnull query, HKStatisticsCollection * _Nullable result, NSError * _Nullable error) { if (error != nil) { // TODO } else { [result enumerateStatisticsFromDate:startOfDay toDate:today withBlock:^(HKStatistics * _Nonnull result, BOOL * _Nonnull stop) { HKQuantity *quantity = [result sumQuantity]; double steps = [quantity doubleValueForUnit:[HKUnit countUnit]]; NSLog(@"Steps : %f", steps); }]; }};[self.storage executeQuery:query];
For swift 4.2
1) Get HealthKitPermission
import HealthKitfunc getHealthKitPermission() { delay(0.1) { guard HKHealthStore.isHealthDataAvailable() else { return } let stepsCount = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)! self.healthkitStore.requestAuthorization(toShare: [], read: [stepsCount]) { (success, error) in if success { print("Permission accept.") } else { if error != nil { print(error ?? "") } print("Permission denied.") } } }}
2) To get steps count for specific date
func getStepsCount(forSpecificDate:Date, completion: @escaping (Double) -> Void) { let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)! let (start, end) = self.getWholeDate(date: forSpecificDate) let predicate = HKQuery.predicateForSamples(withStart: start, end: end, options: .strictStartDate) let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in guard let result = result, let sum = result.sumQuantity() else { completion(0.0) return } completion(sum.doubleValue(for: HKUnit.count())) } self.healthKitStore.execute(query) } func getWholeDate(date : Date) -> (startDate:Date, endDate: Date) { var startDate = date var length = TimeInterval() _ = Calendar.current.dateInterval(of: .day, start: &startDate, interval: &length, for: startDate) let endDate:Date = startDate.addingTimeInterval(length) return (startDate,endDate) }
How to use
self.getStepsCount(forSpecificDate: Date()) { (steps) in if steps == 0.0 { print("steps :: \(steps)") } else { DispatchQueue.main.async { print("steps :: \(steps)") } } }