Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HealthKit Swift getting today's steps

I am making a swift iOS app that integrates with a user's step count as reported by the Health app. I can easily find the user's step count in the last hour, using this as my predicate:

let anHourBeforeNow: NSDate = NSDate().dateByAddingTimeInterval(-60 * 60) let predicate = HKQuery.predicateForSamplesWithStartDate(anHourBeforeNow, endDate: NSDate(), options: .None) 

And I have the rest down, so I can successfully access the user's step count for the last hour. But how can I access the user's step data since the day began, like the Health app displays in the steps section?

I am trying to do something like this:

let date = NSDate() let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! let newDate = cal.startOfDayForDate(date) let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None) 

but this code does not adjust for time zone (so it gives me the beginning of the day in UTC, not the beginning of the day where the user is) and I am also getting highly inflated step counts (for reasons unknown).

So how can I get the user's step count for the current day, with the same number of steps as reported in Health, like pictured here:enter image description here

like image 466
owlswipe Avatar asked Apr 11 '16 21:04

owlswipe


People also ask

Is Apple health the same as HealthKit?

HealthKit is the developer framework behind it that allows apps to work with Apple Health and each other. If you're confused about how the Apple Health app works, what type of information you need to get the most out of it, and which apps are compatible, keep reading.

How do I see my step history on Health app?

The Health app included with iOS 8 and later does indeed save a history of your daily step counts, along with any other fitness and medical information you choose to share with it. To see the information, open the Health app and on the Dashboard screen, tap the orange graph showing your current steps and daily average.

How do I get yesterday's steps on the Health app?

if you want to know yesterday's steps all you need to do is go to settings, date and time, change the date to yesterday, go back to health kit and VOILA !

Where is HealthKit data stored?

To quote: This data is stored in Data Protection class Protected Unless Open. Access to the data is relinquished 10 minutes after device locks, and data becomes accessible the next time user enters their passcode or uses Touch ID or Face ID to unlock the device.


2 Answers

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) } 
like image 75
José Avatar answered Sep 30 '22 14:09

José


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]; 
like image 22
Gugulethu Avatar answered Sep 30 '22 13:09

Gugulethu