Search code examples
iosios8healthkithksamplequery

How to group HKStatistics by hour?


I'm trying to extract step data from HealthKit.

I want to create a summary of step data grouped by hour. Currently, I can extract all of the samples of data between a date range provided by NSPredicate with HKSampleQuery. I could also get a sum of the step count between a date range with HKStatisticsQuery.

What I am asking is if there is a way to sum group the samples or statistics by hour. In SQL I would write something like this:

SELECT HOUR(date), SUM(steps) FROM healthkit WHERE date BETWEEN 'blah' AND 'blah' GROUP BY 1;

Am I seriously going to have to query HKStatistics 24 x 31 times to write the last month of step data grouped by hour? Because that seems rather inefficient, especially with how the resultsHandler is implemented.


Solution

  • You should use an HKStatisticsCollectionQuery where you can perform grouping by time intervals. An example stub code would be:

    NSDate *startDate, *endDate, *anchorDate; // Whatever you need in your case    
    HKQuantityType *type = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    
    // Your interval: sum by hour
    NSDateComponents *intervalComponents = [[NSDateComponents alloc] init];
    intervalComponents.hour = 1;
    
    // Example predicate
    NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:fromDate endDate:toDate options:HKQueryOptionStrictStartDate];
    
    HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:type quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum anchorDate:anchorDate intervalComponents:intervalComponents];
        query.initialResultsHandler = ^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *result, NSError *error) {
            // do something with the results
        };
    [healthStore executeQuery:query];
    

    You can read more details in the HKStatisticsCollectionQuery docs