HealthKit Workout Queries seem really slow

1.4k Views Asked by At

I have some code which is querying data from healthkit. We get various samples and quantities from the healthkit as well as recent workouts. On my phone (usually a workout every day - although the Basis stores things as multiple workouts), the workout query takes about 8 seconds, but all the other types finish in less than a second.

It feels like, under the covers, this query is doing a linear scan where the others are indexed or something. Wondered if anybody else had run into this or had any thoughts?

NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:[self dateByCalculatingWithNumberOfDays:-1 date:[NSDate date]]
                                                           endDate:[NSDate date]
                                                           options:HKQueryOptionStrictStartDate | HKQueryOptionStrictEndDate];

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO];

HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:[HKSampleType workoutType]
                                                       predicate:predicate
                                                           limit:0
                                                 sortDescriptors:@[sortDescriptor]
                                                  resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {

    self.workoutEntries = [[NSMutableArray alloc] initWithCapacity:results.count];
    for (HKWorkout *workout in results) {
        WorkoutObject *workoutObject = [WorkoutObject workoutObjectWithWorkout:workout];
        [self.workoutEntries addObject:workoutObject];
    }
    [self fetchHeartRate];
}];
[self.healthStore executeQuery:query];
1

There are 1 best solutions below

0
On

I did some isolated workout queries and found that they are actually very fast.

It turns out that a previous stage of our HealthKit sync was causing the appearance that workout queries were taking a long time.

Specifically, we were querying about 25 metrics on a per day basis; causing something like 250 queries to be submitted. That workload was all in asyncronous blocks, so was still continuing after the workout query had been submitted; which made it look like it was taking a long time.

The solution was to not query per day, but instead to do a single query for many days that returns results grouped by day - like this: Get total step count for every date in HealthKit

Part of the overhaul also involved doing a better job of using GCD groups to manage completion of the overall task and tracking of the various outstanding calls using the group-enter and group-leave functionality. These two changes improved things considerably.