Search code examples
iosswiftbackground-processappdelegatehealthkit

How to query for HealthKit (HKWorkout) updates when app is in background?


EDIT to add my updated code which I based on WWDC 2016's Getting the Most Out of Healthkit talk, but I still am not getting my print statement with the new workout to fire unless I open the app?

I'm trying to observe for new workouts on the iPhone after they've been saved on the Apple Watch. Below is the code I'm running in didFinishLaunching. To test it, I'm running Xcode on my iPhone App...building and running, then navigating back to the home screen. Then starting and saving a workout on my watch, however my print statements aren't printing in the console. What am I missing?

func startObservingNewWorkouts() {

    let sampleType =  HKObjectType.workoutType()

    //1. Enable background delivery for workouts
    self.healthStore.enableBackgroundDelivery(for: sampleType, frequency: .immediate) { (success, error) in
        if let unwrappedError = error {
            print("could not enable background delivery: \(unwrappedError)")
        }
        if success {
            print("background delivery enabled")
        }
    }

    //2.  open observer query
    let query = HKObserverQuery(sampleType: sampleType, predicate: nil) { (query, completionHandler, error) in

        self.updateWorkouts() {
            completionHandler()
        }


    }
    healthStore.execute(query)

}

func updateWorkouts(completionHandler: @escaping () -> Void) {

    var anchor: HKQueryAnchor?

    let sampleType =  HKObjectType.workoutType()

    let anchoredQuery = HKAnchoredObjectQuery(type: sampleType, predicate: nil, anchor: anchor, limit: HKObjectQueryNoLimit) { [unowned self] query, newSamples, deletedSamples, newAnchor, error in

        self.handleNewWorkouts(new: newSamples!, deleted: deletedSamples!)

        anchor = newAnchor

        completionHandler()
    }
    healthStore.execute(anchoredQuery)


}

func handleNewWorkouts(new: [HKSample], deleted: [HKDeletedObject]) {
    print("new sample added = \(new.last.startTime!)")
}

Solution

  • Turns out this code 👆 works, its just that I was testing in the simulator and apparently the Observer Query does NOT fire when running in the simulator but it DOES fire when running on device