G.Abhisek
G.Abhisek

Reputation: 1094

HKStatisticsCollectionQuery for fetching Heart Rate Health Kit

I have been trying for a while for fetching heart rate in order to plot in a graph. As mentioned in docs heart rate can be fetched by HKStatisticsCollectionQuery. I am trying to fetch a week's data from current date.

But I am unable to get the fetched data. Here is my code below for heart rate accessing using HKStatisticsCollectionQuery :

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *interval = [[NSDateComponents alloc] init];
NSDate *anchorDate = [[NSDate alloc] init];
NSDateComponents *anchorComponents =
    [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth |
     NSCalendarUnitYear | NSCalendarUnitWeekday fromDate:[NSDate date]];

NSDate *currentDisplayEndDate = [NSDate date];
NSDate *newDate = [calendar startOfDayForDate: currentDisplayEndDate];  NSDate *startDate = [newDate dateByAddingTimeInterval:-6*24*60*60];
anchorDate = startDate;
 NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:self.startDate endDate:_currentDisplayEndDate options:HKQueryOptionStrictStartDate];

HKQuantityType *quantityType =
    [HKObjectType quantityTypeForIdentifier:quantityId];

    // Create the query

    HKStatisticsCollectionQuery *query =
    [[HKStatisticsCollectionQuery alloc]
     initWithQuantityType:quantityType
     quantitySamplePredicate:predicate
     options:HKStatisticsOptionDiscreteMax
     anchorDate:anchorDate
     intervalComponents: interval];

    // Set the results handler
    query.initialResultsHandler =
    ^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *results, NSError *error) {

        if (error) {
            // Perform proper error handling here
            NSLog(@"*** An error occurred while calculating the statistics: %@ ***",
                  error.localizedDescription);
        }
        [results
 enumerateStatisticsFromDate:startDate
 toDate:endDate
 withBlock:^(HKStatistics *result, BOOL *stop) {

     HKQuantity *quantity = result.sumQuantity;
     if (quantity) {
         NSDate *date = result.startDate;
         double value = [quantity doubleValueForUnit:[[HKUnit unitFromString:@"count/min"]];

         // Call a custom method to plot each data point.
     }

 }];
    };

    [healthStore executeQuery:query];

My HKStatistics *results is returned as nil.Am I doing something wrong over here?

Upvotes: 1

Views: 1568

Answers (1)

Avinash Kumar Gautam
Avinash Kumar Gautam

Reputation: 98

Problem in not where you thought, The results are returned with statistical query, but in case of heart rate, it does not give heart beat quantity along with that, so HKQuantity *quantity = result.sumQuantity; returns nil.

If you will check properly, you will see that results.statistics will give you some data about recorded heart rate, but no heart rate quantity, rather only, the start and end dates for the recorded data.

I would suggest, go ahead and you HKAnchoredQuery for the same, I will provide the code, here:

-(double)get_heartRates
    {
    //code to heart beats average, modify as needed
    NSDate *startDate1 = [NSDate distantPast];
    NSPredicate *Predicate = [HKQuery predicateForSamplesWithStartDate:startDate1 endDate:[NSDate date] options:HKQueryOptionStrictEndDate];
    HKSampleType *object = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];

    sum_Of_HeartRates=0.0;

    HKAnchoredObjectQuery  *heartQuery = [[HKAnchoredObjectQuery alloc] initWithType:object predicate:Predicate anchor:self.lastAnchor limit:0 resultsHandler:^(HKAnchoredObjectQuery *query, NSArray<HKSample *> *sampleObjects, NSArray<HKDeletedObject *> *deletedObjects, HKQueryAnchor *newAnchor, NSError *error) {

        NSLog(@"Sample counts:%ld",sampleObjects.count);
        for(int i=0;i<(int)sampleObjects.count;i++)
        {
            HKQuantitySample *sample = (HKQuantitySample *)[sampleObjects objectAtIndex:i];
            HKQuantity *quantity = sample.quantity;
            double bpm_Values= [quantity doubleValueForUnit:[HKUnit unitFromString:@"count/min"]];
            sum_Of_HeartRates=sum_Of_HeartRates+bpm_Values;

        }
        avg_heartBeats=sum_Of_HeartRates/(int)sampleObjects.count;
    }];
    [heartQuery setUpdateHandler:^(HKAnchoredObjectQuery *query, NSArray<HKSample *> *SampleArray, NSArray<HKDeletedObject *> *deletedObjects, HKQueryAnchor *Anchor, NSError *error) {

        HKQuantitySample *sample = (HKQuantitySample *)[SampleArray objectAtIndex:0];
        HKQuantity *quantity = sample.quantity;
        new_Updated_Data =[quantity doubleValueForUnit:[HKUnit unitFromString:@"count/min"]];
        NSLog(@"new quantity:%f",new_Updated_Data);
    }];
    [self.healthStore executeQuery:heartQuery];
    NSLog(@"updated data %f",new_Updated_Data);
    return avg_heartBeats;
}

Upvotes: 4

Related Questions