querying steps data without stopping query

My app requires that new steps data be automatically retrieved. can this be made possible by not stopping the query and let it remain running?


the query returns and array. will i have a new array whenever steps data has an update for the query?

Accepted Reply

Sorry, I have no experience with obj c.


"The way i plan to implement is to just observe if there are any changes. If there are then run the original query to retrieve those changes."


That's exactly what HKObserverQuery does. See documentation: https://developer.apple.com/documentation/healthkit/hkobserverquery/executing_observer_queries


-> "The observer query’s update handler does not receive any information about the change—just that a change occurred. You must execute another query, for example an

HKSampleQuery
or
HKAnchoredObjectQuery
, to access the changes.
"

Replies

Check out HKObserverQuery

I am finding it hard to understand HKObserverQuery especially with no obj c code for the same in the Documentation. I couldn't find a tutorial on the same with obj c code either. Can you tell me a workaround?

The way i plan to implement is to just observe if there are any changes. If there are then run the original query to retrieve those changes. Is that the way it works?

Sorry, I have no experience with obj c.


"The way i plan to implement is to just observe if there are any changes. If there are then run the original query to retrieve those changes."


That's exactly what HKObserverQuery does. See documentation: https://developer.apple.com/documentation/healthkit/hkobserverquery/executing_observer_queries


-> "The observer query’s update handler does not receive any information about the change—just that a change occurred. You must execute another query, for example an

HKSampleQuery
or
HKAnchoredObjectQuery
, to access the changes.
"

Ol. So i have understood it correctly. All the swift code was confusing me.

so if I understand the documentatio right...


  1. I initialise an HKObserverQuery For foreground observation of updates
  2. I execute the HKSampleQuery from the completion handler of Observer query
  3. for background observation I call enableBackgroundDeliveryForType from applicationaDidFinishLaunching
  4. I pass a HKObserverQueryCompletionHandler block to enableBackgroundDeliveryForType to receive the update in background


Do I execute the same HKSampleQuery in the enableBackgroundDeliveryForType Completion handler to query the steps data?

Here is my code...


Calories.m


-(void)queryForQuantityTypeIdentifier: (HKQuantityTypeIdentifier)quantityTypeIdentifier;
{
HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:quantityTypeIdentifier];
    HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:nil limit:HKObjectQueryNoLimit sortDescriptors:nil resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
        if (!results) {
            NSLog(@"Error is fetching %@ %@",quantityTypeIdentifier, error);
        }
        else if(results.count>0)
        {
            if (quantityTypeIdentifier == HKQuantityTypeIdentifierStepCount)
            {
                self->_stepsTakenSampleArray = [results mutableCopy];
            }
            dispatch_async(dispatch_get_main_queue(), ^(){
                NSNotification *stepsDataRetrivedNotification = [NSNotification notificationWithName:@"StepsDataRetrivedNotification" object:nil];
                [[NSNotificationCenter defaultCenter] postNotification:stepsDataRetrivedNotification];
            });
        
        }
        [self->store stopQuery:query];
    }];
    dispatch_async(dispatch_get_main_queue(), ^{
        self->appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        self->store = [[self->appDelegate hkOperator] hkStore];
        [self->store executeQuery:query];
    });
}

HealthKitOperator.m


-(void)enableStore
{
    _hkStore= [[HKHealthStore alloc] init];
    [self requestPermissions];
    HKSampleType *quantityType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];

     stepsObserverQuery = [[HKObserverQuery alloc] initWithSampleType:quantityType predicate:nil updateHandler:^(HKObserverQuery *query,HKObserverQueryCompletionHandler completionHandler, NSError *error) {
         if (completionHandler) {
             dispatch_async(dispatch_get_main_queue(), ^()
                            {
                 [self->_calories querySteps];
             });
         }
      }];
     [_hkStore executeQuery:stepsObserverQuery];
}

AppDelegate.m


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if (_hkOperator.hkAuthorised)
    {
        [_hkOperator.hkStore enableBackgroundDeliveryForType: [HKQuantityType quantityTypeForIdentifier: HKQuantityTypeIdentifierStepCount] frequency:HKUpdateFrequencyHourly withCompletion:^(BOOL success, NSError *error) {
            [self->_hkOperator.calories querySteps];
        }];
    }
   
    return YES;

}