I am trying to have HealthKit launch my app whenever there is new data available. So I tried to use HKObserverQuery with background delivery following this example that I find on GitHub.
I have the background modes capability enabled for my project and made sure there is only 1 item in Required background modes in Info.plist
I am using Xcode and IOS 10. I do realize there is time limit on certain data types so I tested this is by adding flights climbed to the health app on the simulator and see if the print method is called. But nothing is happening. I also tried to set break points in the application() method in AppDelegate but it is only executed on the first launch of the app. It is not called after I put entries in the health app.
What am I doing wrong here? Or is there some way to see if Healthkit is trying to launch my app?
here is my AppDelegate and other relevant files
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let manager = HealthKitManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
manager.hkAccessor.setUpObserverQuery(){ samples in
for sample in samples!{
print("\(sample.value) \(sample.identifier)")
}
}
return true
}
HealthkitAccessor:
func setUpObserverQuery(completion:@escaping ([QuantitySample]?) -> ()) {
for type in getDataTypesToRead() {
guard let sampleType = type as? HKSampleType else { print("\(type) is not an HKSampleType"); continue }
let query = HKObserverQuery(sampleType: sampleType, predicate: nil) {
[weak self] query, completionHandler, error in
if error != nil {
print("*** An error occured. \(error!.localizedDescription) ***")
return
}
guard let strongSelf = self else { return }
strongSelf.queryForDataType(type:type) { samples in
completion(samples)
}
completionHandler()
}
executeQuery(query: query)
healthStore.enableBackgroundDelivery(for: type, frequency: .immediate) { (success: Bool, error: Error?) in
if success{
print("\(type) registered for background delivery")
}
else {
print("\(type) registered for background delivery")
}
}
}
}
After 12 hours of trying, I found that what I had actually works. Just not on a simulator. It works on real devices with some delay, which is reasonable. I have seen people saying that HealthKit can't notify your app immediately after update of the data, instead it finds opportunity that the system is not busy to wake your app.