HealthKit cannot read steps data

2019-07-25 06:59发布

问题:

I'm working with HealthKit to read steps data from my iOS device.

here is my code:

if ([HKHealthStore isHealthDataAvailable]) {
        __block double stepsCount = 0.0;
        self.healthStore = [[HKHealthStore alloc] init];
        NSSet *stepsType =[NSSet setWithObject:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]];
        [self.healthStore requestAuthorizationToShareTypes:nil readTypes:stepsType completion:^(BOOL success, NSError * _Nullable error) {
            if (success) {
                HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
                HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:nil limit:HKObjectQueryNoLimit sortDescriptors:nil resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
                    if (error != nil) {
                        NSLog(@"results: %lu", (unsigned long)[results count]);
                        for (HKQuantitySample *result in results) {
                            stepsCount += [result.quantity doubleValueForUnit:[HKUnit countUnit]];
                        }
                        NSLog(@"Steps Count: %f", stepsCount);
                    } else {
                        NSLog(@"error:%@", error);
                }];
                [self.healthStore executeQuery:sampleQuery];
                [self.healthStore stopQuery:sampleQuery];

                NSLog(@"steps:%f",stepsCount);
            }
        }];
    }

I build and run the code on an iPhone6 which does have steps data and in the Settings -> Privacy -> Health, the app does have been allowed to read data, but the log area only shows:

steps:0.000000

I put a break point on the for-loop and on the NSLog(@"error:%@", error), but the app does not break.

Anybody can help?

回答1:

Your code stops the query immediately, before it has a chance to run. For this query, there is no reason to call stopQuery: at all unless you want to cancel a query before it finishes. Since the query is not long lived (it doesn't have an updateHandler), it will stop immediately after the resultsHandler is called.

The second problem is that your code attempts to log step count too soon. The query runs asynchronously, and the resultsHandler will be called on a background thread once the query completes. I'd suggest logging stepsCount inside the block.

Finally, if you want to count the user's steps you should us an HKStatisticsQuery instead of summing the results of an HKSampleQuery. HKStatisticsQuery is more efficient and will yield correct results when there are multiple sources of overlapping data in HealthKit. Your current implementation will double count the user's steps if they have both an iPhone and an Apple Watch, for instance.



回答2:

Try this code u just change the start date and End date.

-(void) getQuantityResult
{
NSInteger limit = 0;
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:currentDate endDate:[[NSDate date]dateByAddingTimeInterval:60*60*24*3] options:HKQueryOptionStrictStartDate];

NSString *endKey =  HKSampleSortIdentifierEndDate;
NSSortDescriptor *endDate = [NSSortDescriptor sortDescriptorWithKey: endKey ascending: NO];

HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType[HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]
                                                   predicate: predicate
                                                       limit: limit
                                             sortDescriptors: @[endDate]
                                              resultsHandler:^(HKSampleQuery *query, NSArray* results, NSError *error){
                                                    dispatch_async(dispatch_get_main_queue(), ^{
                                                      // sends the data using HTTP
                                                      int dailyAVG = 0;
                                                      for(HKQuantitySample *samples in results)
                                                                   {
                                                          dailyAVG += [[samples quantity] doubleValueForUnit:[HKUnit countUnit]];
                                                       }
                                                      lblPrint.text = [NSString stringWithFormat:@"%d",dailyAVG];
                                                      NSLog(@"%@",lblPrint.text);
                                                      NSLog(@"%@",@"Done");
                                                  });
                                              }];
  [self.healthStore executeQuery:query];
}