HKObserverQuery
has the following method that supports receiving updates in the background:
- initWithSampleType:predicate:updateHandler:
The updateHandler
has a completionHandler
which has the following documentation:
This block is passed to the update handler. You must call this block as soon as you are done processing the incoming data. Calling this block tells HealthKit that you have successfully received the background data. If you do not call this block, HealthKit continues to attempt to launch your app using a backoff algorithm. If your app fails to respond three times, HealthKit assumes that your app cannot receive data, and stops sending you background updates.
From looking at other posts it seems like there's a lot of confusion revolving around this handler. Below are some questions that I have about it:
- When should the handler be called? If called too late, then HK might think that the app never received the query update causing you to hit the background update 3-strikes back-off algorithm. The documentation states that it should be called after handling other queries. Depending on how long it would take to run those queries, it sounds like you could get dangerously close to hitting the background update strikes.
- Why is this needed? Shouldn't the system know that the app has been launched and has received the background update? When using
CoreBluetooth
in the background it just wakes your app up in the background for 10 seconds. No need to call any handler or deal with the background update 3-strikes. - If you hit the background update 3-strikes and HK stops sending updates is that permanent? Does HK ever start sending the background updates again? What if there's a bug that prevented the handler to be called and now you've fixed it. Is the app stuck never receiving the updates? Or will it reset when the app is re-launched or updated?
- Does HK keep your app running in the background until the handler is called? Is that part of its purpose or just a side effect? If it's part of its purpose how long can we run before needing to stop (and hit the first background update strike)?