Apple HealthKit
Apple HealthKit is an SDK-based provider. Your iOS consumer app would embed the Vital Mobile SDKs on a supported stack. Data are then pulled from the Apple HealthKit data store on the user’s iOS device.
Refer to the Mobile SDK Installation and Vital Health SDK guides for SDK installation instructions and general API usage. This guide contains information on the the behaviour and required configuration specific to the Apple HealthKit integration.
Sync Frequency
App state | Behaviour |
---|---|
Foreground | Apple HealthKit delivers any buffered and new changes immediately. |
Background | Hourly batch delivery of changes, subject to operating system throttling. |
While the SDK schedules hourly data sync with Apple HealthKit, iOS has full discretion to defer the scheduled time based on factors like CPU usage, battery usage, connectivity, and Low Power Mode.
In other words, the Vital SDK — or any third-party HealthKit apps — cannot guarantee the sync to happen on a strict schedule. The hourly schedule is advisory and non-binding from the persective of iOS. The actual delivery frequency can therefore fluctuate from hourly, to once a day, or when certain opportunity arises (e.g., when Sleep Mode ends, or when the phone starts charging).
Background Delivery
The iOS SDK can support observing new HealthKit data even when your app is not actively being used by your app user. This provides a more seamless experience, since the app user need not periodically open your app to sync data.
1. Setup app entitlements
Enable the “HealthKit > Background Delivery” entitlement:
Enable the “Background Modes > Background Processing entitlement:
2. Update your Info.plist
In your “Info > Custom iOS Target Properties” section — also known as the Info.plist
file — these entries should be
configured:
Key | Value |
---|---|
Privacy - Health Share Usage Description ( NSHealthShareUsageDescription ) | An explanation of your usage of the user’s HealthKit data. |
Permitted background task scheduler identifiers ( BGTaskSchedulerPermittedIdentifiers ) | Include io.tryvital.VitalHealthKit.ProcessingTask in the array, alongside any other BGTask identifiers of yours. |
If you request write permissions, you must also specify:
Key | Value |
---|---|
Privacy - Health Update Usage Description ( NSHealthUpdateUsageDescription ) | An explanation of what user health data your app is writing to Apple HealthKit. |
3. Integrate with iOS system callbacks
You must call VitalHealthKitClient.automaticConfiguration()
during application(_:didFinishLaunchingWithOptions:)
of your UIKit UIApplicationDelegate
.
This applies to all iOS integrations, be it Native, React Native or Flutter.
This ensures that Vital has the opportunity to register all handlers before the app “finished launching” as per Apple HealthKit’s specific timing requirement. Background delivery may be missed if this timing requirement is not satisfied.
As per the documentation:
As soon as your app launches, HealthKit calls the update handler for any observer queries that match the newly saved data. If you plan on supporting background delivery, set up all your observer queries in your app delegate’s application(_:didFinishLaunchingWithOptions:) method. By setting up the queries in
application(_:didFinishLaunchingWithOptions:)
, you ensure that you’ve instantiated your queries, and they’re ready to use before HealthKit delivers the updates.
In other words, make sure VitalHealthKitClient.automaticConfiguration()
is called inside your UIKit App Delegate’s application(_:didFinishLaunchingWithOptions:)
method.
For React Native and Flutter SDK consumers, this means you must configure this directly in native code (Swift / Objective-C). Typically, an App Delegate would have been already created as part of your generated React Native or Flutter Xcode project.
Your AppDelegate
should then look like this:
Swift / Flutter iOS:
import VitalHealthKit
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
VitalHealthKitClient.automaticConfiguration()
/// your code
return true
}
}
Objective-C / React Native iOS:
#import "AppDelegate.h"
#import "VitalHealthKitConfiguration.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[VitalHealthKitConfiguration automaticConfiguration];
/// your code
return YES;
}
3. Epilogue
You are all set!
Note that there is no need to call syncData()
manually at all. Once you have asked the user for permission on
resources, sync would automatically starts every app launch, as well as whenever your app is woken up by Apple HealthKit to
respond to newly available data.
As per the documentation:
HealthKit wakes your app whenever a process saves or deletes samples of the specified type. The system wakes your app at most once per time period defined by the specified frequency. Some sample types have a maximum frequency of
HKUpdateFrequency.hourly
. The system enforces this frequency transparently.For example, on iOS,
stepCount
samples have an hourly maximum frequency.
This means that although we have background delivery’s frequency set to .hourly
, we cannot guarantee hourly syncing on the dot.