1

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")
            }
        }
    }
}
lzt
  • 98
  • 6

1 Answers1

1

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.

lzt
  • 98
  • 6