HealthKit does not launch app when new data is added and hkObserverQuery is set up

396 Views Asked by At

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")
            }
        }
    }
}
1

There are 1 best solutions below

0
On

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.