2

I am trying to perform some actions triggered by changes to Apple Health Kit, triggered in the background of my Swift iOS app.

Here's my AppDelegate:

var healthManager : HealthManager?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


    healthManager = HealthManager.sharedInstance


    return true
}

And in the initialization of the HealthManager class I authorize use of Health Kit and call:

    var sampleType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)
    var predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: HKQueryOptions.StrictStartDate)
    var query = HKObserverQuery(sampleType: sampleType, predicate: predicate, updateHandler: stepsChangedHandler)

    healthKitStore.executeQuery(query)
    healthKitStore.enableBackgroundDeliveryForType(sampleType, frequency: .Immediate, withCompletion: {(succeeded, error) in
        if succeeded {
            println("Enabled background delivery of step changes")
        } else {
            if let theError = error {
                print("Failed to enable background delivery of step changed. ")
                println("Error = \(theError)")
            }
        }
    })

This works beautifully when the app is open- the stepsChangedHandler is called when there's a health kit update, but when the app is out of focus it never is called. I've searched around and found a few ideas, but none of the fixes have seemed to work for me.

Thanks!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
michael5w
  • 71
  • 7
  • I too am wondering how to successfully do this. Does anyone know the application lifecycle of a HealthKit-awoken background app? Does appdelegate get instantiated? I'm starting to think ONLY the updateHandler for the observer query is run. – Jake Stout Jun 30 '15 at 19:44
  • @barnone - I put a println in the updateHandler to see if anything was happening when in the background, but it never shows on the Xcode console, but perhaps those don't work that way? – michael5w Jun 30 '15 at 20:23
  • @barnone - I've posted an answer explaining the life cycle here: http://stackoverflow.com/questions/31117630/does-the-appdelegate-initialize-when-healthkit-wakes-my-app-in-the-background/31904007#31904007 – goldengil Oct 07 '15 at 12:29
  • @goldengil thanks. i've got it to work as well. I guess the bigger picture problem is... most of those updates happen when the phone is locked (and so the data can't be pulled). Any ideas how you might tell the iPhone to try again once unlocked? – michael5w Oct 08 '15 at 12:04
  • Look at my answer here: http://stackoverflow.com/a/35073904/1677480 – damirstuhec Jan 28 '16 at 23:25

2 Answers2

1

What you have should work, but my experience with the simulator up through iOS 8.4 and Xcode 6.4 is that the background updates are not triggered. However, in my testing this does work on a device. To try for yourself, hook up and run your app on a device then switch to Health.app and add a relevant data point.

If your query is set for immediate updates, you should see your log message in the console. Make sure stepsChangedHandler includes completionHandler().

According to the docs, the query runs on a separate background thread so your appdelegate code will only be called on initial launch.

zjames
  • 729
  • 11
  • 14
1

In the documentation for the HKHealthStore Class, under enableBackgroundDeliveryForType:... there is a paragraph:

Some data types, such as step counts, have a minimum frequency of HKUpdateFrequencyHourly. This frequency is enforced transparently.

which explains why you won't see background updates as frequently as you are specifying. I'm not sure if theres a listing of which data types are included in the "some" quantifier.

Jeff
  • 56
  • 3