I use the code below to have my app detect updates to HealthKit data in the background. Will the init method of my AppDelegate be called when this code is run in the background? What methods in the AppDelegate will be called? If someone can provide documentation about the application lifecycle of background code, that will be much appreciated!
[healthStore enableBackgroundDeliveryForType:type frequency:HKUpdateFrequencyHourly withCompletion:^(BOOL success, NSError *error) {
if (success) {
HKObserverQuery *observerQuery = [[HKObserverQuery alloc] initWithSampleType:type
predicate:nil
updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error) {
if (!error) {
[self retrieveHealthDataWithCompletionHandler:completionHandler];
}
}];
[healthStore executeQuery:observerQuery];
}
A bit late but hopefully, it would still help you or anyone else who reach here..
When your app delegate’s application:didFinishLaunchingWithOptions
: method is being called you can assume the app launches. Thats why Apple recommend you'll register any observer queries you'd like to have inside that method.
When there will be new data of the type you registered for, HealthKit will wake your app. (So far you still don't know anything about any new data.) Once your app finish its launching it will call the beloved app delegate’s application:didFinishLaunchingWithOptions
: method, which as stated before, should contain the code of registering the observer queries.
Once you register your queries, next thing will be getting an update about new data (this is the purpose of observer queries).
Getting the update about something new in HealthKit doesn't contain the data itself. Thats why in the updateHandler of the observer query you should initiate anther query - a more specific one that will fetch the wanted data.
That's it. I would make some changes in the code you provided in order for it to work:
[healthStore enableBackgroundDeliveryForType:type frequency:HKUpdateFrequencyHourly withCompletion:^(BOOL success, NSError *error) {
if (success) {
//Nothing much to do here
}
}];
HKObserverQuery *observerQuery = [[HKObserverQuery alloc] initWithSampleType:type
predicate:nil
updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error) {
if (!error) {
//Create and execute a query about the sample type.
// Within the completion handler of the new query, don't forget to call completionHandler()
}
}];
[healthStore executeQuery:observerQuery];
You can find more details here:
Receiving Background Deliveries
Apps can also register to receive updates while in the background by calling the HealthKit store’s enableBackgroundDeliveryForType:frequency:withCompletion:
method. This method registers your app for background notifications. HealthKit wakes your app whenever new samples of the specified type are saved to the store. Your app is called at most once per time period defined by the frequency you specified when registering.
As soon as your app launches, HealthKit calls the update handler for any observer queries that match the newly saved data. If you plan on supporting background delivery, set up all your observer queries in your app delegate’s application:didFinishLaunchingWithOptions
: method. By setting up the queries in application:didFinishLaunchingWithOptions
:, you ensure that the queries are instantiated and ready to use before HealthKit delivers the updates.
After your observer queries have finished processing the new data, you must call the update’s completion handler. This lets HealthKit know that you have successfully received the background delivery.