Search code examples
iosobjective-cxcodehealthkithksamplequery

Trouble Retrieving Heart Rate Data from HealthKit


I currently have two records of heart rate earlier this year in January stored in my Health App. In the current app I'm making, I give access to read and write heart rate data.

In my viewDidAppear for one of my view controller's, I'm attempting to read the heart rate records. However, I'm unsuccessful in retrieving any data.

Here is my read heart rate data code:

+ (void)readHeartRateWithCompletion:(void (^)(NSArray *results, NSError *error))completion {

    HKQuantityType *heartRateType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];

    NSSortDescriptor *timeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierStartDate ascending:YES];

    NSDate *lastSample = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastTsUploaded"];
    if (!lastSample) {
        lastSample = [NSDate dateWithTimeIntervalSinceNow:-24 * 60 * 60];
    }

    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
    NSDate *now = [NSDate date];
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *comps = [gregorian components:unitFlags fromDate:now];
    [comps setYear:[comps year] - 2];
    NSDate *hundredYearsAgo = [gregorian dateFromComponents:comps];

    NSPredicate *pred = [HKQuery predicateForSamplesWithStartDate:hundredYearsAgo endDate:[NSDate date] options:HKQueryOptionStrictStartDate];

    HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:heartRateType predicate:pred limit:10 sortDescriptors:@[timeSortDescriptor] resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
        if (!results) {
            NSLog(@"There are no heart rate results. The error was: %@.", error);
            return;
        }
    }];

    [[dcsContext sharedContext].healthStore executeQuery:sampleQuery];
}

Why is my query not returning any data?


Solution

  • I FINALLY figured it out after hours and hours of pulling my hair trying to understand why none of my queries were being executed. I had to add the following before all my code:

    if ([HKHealthStore isHealthDataAvailable]) {
    
    self.healthStore = [[HKHealthStore alloc] init];
    
    // Rest of my code below
    
    //get the heart rates
    NSDate *now = [NSDate date];
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:now];
    ...
    

    I also replaced my [[dcs sharedContext].healthStore] with another instance of healthstore that I added as a property to my VC. I'll turn this into a singleton later as recommended by Apple, but for now this fix works.