Share health and fitness data with other apps, while maintaining the user’s privacy and control over their data.
- iOS 8.0+
- watchOS 2.0+
HealthKit stores data from apps on iPhone and Apple watch. It also works directly with some health and fitness devices. In iOS 8.0, the system can automatically save data from compatible Bluetooth LE heart rate monitors. The system can also automatically import activity data from the M7 motion coprocessor, if available. Other devices and data sources must have a companion app that can access the data and save it to HealthKit for them.
HealthKit saves data in an encrypted database called the HealthKit store. You can access this database using the
HKHealthStore class. Both iPhone and Apple Watch have their own HealthKit store. Health data is synced between Apple Watch and iPhone; however, old data is periodically purged from Apple Watch to save space. Use the
earliestPermittedSampleDate() method to determine the age of the oldest sample on Apple Watch.
HealthKit is designed to manage data from a wide range of sources, automatically merging the data from different sources based on user’s preferences. Apps can also access the raw data for each source, merging the data themselves.
HealthKit provides an app to help manage the user’s health data. The Health app acts as the user’s interface to the HealthKit data. Users can view, add, delete, and otherwise manage all of their health and fitness data using this app. They can also edit the sharing permissions for each data type.
HealthKit and the Health app are unavailable on iPad.
Protecting User Privacy
Because health data can be sensitive, HealthKit grants users control over their data by providing fine-grained control over the information that apps can share. The user must explicitly grant each app permission to read and write data to the HealthKit store. Users can grant or deny permission separately for each type of data. For example, a user could let your app read the step count data but prevent it from reading the blood glucose level. To prevent possible information leaks, an app does not know whether it has been denied permission to read data. From the app’s point of view, if the app has been denied permission to read data, no data of that type exists.
The HealthKit data is only kept locally on the user’s device. For security, the HealthKit store is encrypted when the device is locked. The HealthKit store can only be accessed by an authorized app. As a result, you may not be able to read data from the store when your app is launched in the background; however, apps can still write data to the store, even when the phone is locked. HealthKit temporarily caches the data and saves it to the encrypted store as soon as the phone is unlocked
In addition, your app must not access the HealthKit APIs unless the app is primarily designed to provide health or fitness services. Your app's role as a health and fitness service must be clear in both your marketing text and your user interface. Specifically, the following guidelines apply to all HealthKit apps:
Your app may not use information gained through the use of the HealthKit framework for advertising or similar services. Note that you may still serve advertising in an app that uses the HealthKit framework, but you cannot use data from the HealthKit store to serve ads.
You must not disclose any information gained through HealthKit to a third party without express permission from the user. Even with permission, you can only share information to a third party if they are also providing a health or fitness service to the user.
You cannot sell information gained through HealthKit to advertising platforms, data brokers, or information resellers.
If the user consents, you may share his or her HealthKit data with a third party for medical research.
You must clearly disclose to the user how you and your app will use their HealthKit data.
Personal Health Record model (for non-HIPAA apps): http://www.healthit.gov/policy-researchers-implementers/personal-health-record-phr-model-privacy-notice
HIPAA model (for HIPAA covered apps): http://www.hhs.gov/ocr/privacy/hipaa/modelnotices.html
Working with the HealthKit Framework
The HealthKit framework is designed to share data between apps in a meaningful way. The framework constrains the types of data and units to a predefined list, ensuring that all apps understand what the data means and how it can be used. Developers cannot create custom data types or units. Instead, HealthKit provides a wide variety of data types and units.
Additionally, the framework uses a large number of subclasses, producing deep hierarchies of similar classes. Often, these classes have subtle but important differences between them. For example, an
HKQuantitySample object is used to store data with a numeric value, while an
HKCategorySample object is used to store a value selected from an enumeration.
HealthKit also uses pairs of closely related classes. These classes must be paired correctly. For example, the
HKObjectType abstract classes have largely parallel hierarchies of concrete subclasses. When working with objects and object types, you must use matching subclasses.
HealthKit saves a variety of data types in the HealthKit Store:
Characteristic data. These records represent items that typically do not change. This data includes the user’s birthdate, blood type, biological sex, and skin type. You can read this data directly from the HealthKit store, using the
fitzpatrickSkinType()methods. Your application cannot save characteristic data. The user must enter or modify this data using the Health app.
Sample data. Most of the user’s health data is stored in samples. These samples represent data at a particular point in time. All sample classes are subclasses of the
HKSampleclass, which is a subclass of the
HKObjectclass. These classes are described in more detail in Properties of Objects and Samples.
Source data. Each sample stores information about its source. The
HKSourceRevisionobject contains information about the app or device that saved the sample. The
HKDeviceobject contains information about the hardware device that generated the data.
Deleted objects. An
HKDeletedObjectinstance is used to temporarily store the UUID of an item that has been deleted from the HealthKit store. You can use deleted objects to respond when an object is deleted by the user or another app. For more information, see
Properties of Objects and Samples
UUID. A unique identifier for that particular entry.
Metadata. A dictionary containing additional information about the entry. The metadata can contain both predefined and custom keys. The predefined keys facilitate the sharing of data between apps. Custom keys help extend a given HealthKit object type, adding app-specific data to the entry.
Source Revision. The source of the sample. The source can be a device that directly saves data into HealthKit, or an app. HealthKit automatically records each object’s source and version when the object is saved to the HealthKit store. This property is available only on objects retrieved from the store.
Device. The hardware device that generated the data stored in this sample.
HKSample class is a subclass of
HKObject. Sample objects represent data at a particular point in time. All sample objects are subclasses of the
HKSample class. They all have the following properties:
Type. The sample type; for example, a sleep analysis sample, a height sample, or a step count sample.
Start date. The sample’s start time.
End date. The sample’s end time. If the sample represents a single point in time, the end time should equal the start time. If the sample represents data collected over a time interval, the end time should occur after the start time.
Samples are further divided into four concrete subclasses:
Category samples. Data that can be classified into a finite set of categories. See
Quantity samples. Data that can be stored as numeric values. Quantity samples are the most common data types in HealthKit. These include the user’s height and weight, as well as other data such as the number of steps taken, the user’s temperature, and their pulse rate. See
Correlations. Composite data containing one or more samples. In iOS 8.0, HealthKit uses correlations to represent food and blood pressure. You should always use a correlation when creating food or blood pressure data. See
Workouts. Data representing a physical activity, like running, swimming, or even play. Workouts often have type, duration, distance, and energy burned properties. You can also associate a workout with a number of fine-grained samples. Unlike correlations, these samples are not contained within the workout—however, they can be queried using the workout. For more information, see
Setting Up HealthKit
To set up HealthKit:
In Xcode, enable the HealthKit capabilities for your app.
For more information, see Adding HealthKit (iOS, WatchKit Extension).
Confirm whether HealthKit is available on the user’s device by calling the
isHealthDataAvailable()method, as shown below.
HealthKit is not available on iPad. If HealthKit is not available, other HealthKit methods fail with an
If HealthKit is both enabled and available, instantiate an
HKHealthStoreobject for your app as shown below.
You need only a single HealthKit store per app. These are long-lived objects. Create the store once, and keep a reference for later use.
Request authorization from the user to read and share HealthKit data.
You must do this before you can perform any tasks with your store. To help protect the user’s privacy, HealthKit requires fine-grained authorization. You must request permission to both read and share each data type used by your app.
Any time your app requests new permissions, the system displays a form with all the requested data types shown. The user can toggle individual read and share permissions on and off. To learn how to provide a great user experience when asking for permissions, see HealthKit in iOS Human Interface Guidelines.
Figure 1 shows the permission sheet for the Fit app . To download the sample code, see Fit: Store and Retrieve HealthKit Data.
Provide custom messages to display in the permissions sheet in your app’s
Info.plistfile. A custom message is required for both reading and writing HealthKit data. Set the
NSHealthShareUsageDescriptionkey to customize the message for reading data. Set the
NSHealthUpdateUsageDescriptionkey to customize the message for writing data. For more information, see iOS Keys in Information Property List Key Reference.
Before attempting to save user data, make sure your app is authorized to share data using the HealthKit method. Attempts to save data before permission has been requested fail with an
errorAuthorizationNotDeterminederror. Attempts to save data when permission has been denied fail with a
After the user grants permission to share a data type, you can:
For a practical example, of how to setup and use HealthKit, see Fit: Store and Retrieve HealthKit Data.
Adding Samples to the HealthKit Store
Your app can create new samples and add them to the HealthKit store. The general procedure is similar for all sample types, although each type has its own variations on this theme.
Look up the correct type identifier in HealthKit Constants.
Instantiate an object of the matching
HKSamplesubclass, using the object type.
Save the object to the HealthKit store using the
HKSample subclass has its own convenience methods for instantiating sample objects. These methods modify the procedure above.
For quantity samples, create an instance of the
HKQuantity class. The quantity’s units must correspond to the allowable units described in the type identifier’s documentation. For example, the
height documentation states that it uses length units. Therefore, your quantity must use centimeters, meters, feet, inches, or another compatible unit. For more information, see
For category samples, the sample’s value must correspond to the enum described in the type identifier’s documentation. For example, the
sleepAnalysis documentation states that it uses the
HKCategoryValueSleepAnalysis enum. Therefore, you must pass a value from this enum when creating this sample. For more information, see
For correlations, you must first create all the sample objects that the correlation will contain. The correlation’s type identifier describes both the type and the number of objects that can be contained. Do not save the contained objects into the HealthKit store. They are stored as part of the correlation. For more information, see
Workouts behave somewhat differently than other samples:
You do not need a specific type identifier to create the
HKWorkoutTypeinstance. All workouts use the same type identifier.
You must provide an
HKWorkoutActivityTypevalue for each workout. This value defines the type of activity performed during the workout.
After the workout is saved to the HealthKit store, you must associate additional samples with the workout (for example, active energy burned or distance samples). These samples provide fine-grained details about the workout. For more information, see
Workout samples can contribute to the Move and Exercise rings in the Activity app. To contribute, you must associate one or more active energy burned samples with the workout. Additionally:
In watchOS. Use a workout session to track the user’s activity. When the session has ended, create a workout object and the associated active energy burned samples. For more information, see
The system updates the Move ring based on the active energy burned samples. It updates the Exercise ring based on the amount of time the user spent actually exerting themselves during the workout session, as calculated by the watch’s sensors.
In iOS 10 or later. No additional work is necessary. Workout objects automatically contribute to both the Move and Exercise rings. The Exercise ring is increased by the workout’s total duration, and the Move ring is increased by the number of calories in the associated active energy burned samples. HealthKit also increases the Stand ring by one hour for each wall-clock hour that the workout overlaps.
In iOS 9. Workout objects saved on iPhone do not contribute to the activity rings.
Create and save workouts on the device that makes the most sense for your application. This will typically be the device that is running the logic for the user's workout.
Balancing Performance and Details
When saving data to the HealthKit store, you often need to choose between using a single sample to represent the data, or splitting the data across multiple, smaller samples. A single, long sample is better from a performance perspective; however, multiple smaller samples gives the user a more detailed look into how their data changes over time. Ideally, you want to find a sample size that is granular enough to provide the user with useful historical data.
When recording a workout, you can use high frequency data (a minute or less per sample) to provide intensity charts and otherwise analyze the user’s performance over the workout. For less intensive activity, like daily step counts, samples of an hour or less often work best. This lets you produce meaningful daily and hourly graphs.
Apps should avoid saving samples that are 24-hours long or longer.
Accessing HealthKit Data
There are three main ways to access data from the HealthKit Store:
Direct method calls. The HealthKit store provides methods to directly access characteristic data. These methods can be used only to access characteristic data. For more information, see
Queries. Queries return the current snapshot of the data in the HealthKit store. All queries run on an anonymous background queue. When the query is complete, it executes the results handler on the background queue. HealthKit provides different types of queries, each designed to return different types of data from the HealthKit store.
Sample query. This is a general-purpose query. Use sample queries to access any type of sample data. Sample queries are particularly useful when you want to sort the results or limit the total number of samples returned. For more information, see
Anchored object query. Use this query to search for items that have been added to or deleted from the store. The first time an anchor query is run, it returns all the matching samples currently in the store. On subsequent runs, it returns only those items that have been added or deleted since the last run. For more information, see
Statistics query. Use this query to perform statistical calculations over the set of matching samples. You can use statistics queries to calculate the sum, minimum, maximum, or average value in the set. For more information, see
Statistics collection query. Use this query to perform multiple statistics queries over a series of fixed-length time intervals. You will often use these queries when creating graphs. They provide a simple method for calculating things such as the total number of calories consumed each day or the number of steps taken in each 5-minute interval. For more information, see
Correlation query. Use this query to perform complex searches of the data contained in a correlation. These queries can contain individual predicates for each of the sample types stored in the correlation. If you just want to match the correlation type, use a sample query instead. For more information, see
Source query. Use this query to search for sources (apps and devices) that have saved matching samples to the HealthKit store. A source query lists all the sources that are saving a particular sample type. For more information, see
Activity summary query. Use this query to search for activity summary information for the user. Each activity summary object contains a summary of the user’s activity for a given day. You can query for either a single day or a range of days. For more information, see
Document query. Use this query to search for health documents. For more information, see
Long running queries. These queries continue to run an anonymous background queue, and update your app whenever changes are made to the HealthKit store. In addition, observer queries can register for background delivery. This lets HealthKit wake your app in the background whenever an update occurs.
Observer query. This long-running query monitors the HealthKit store and alerts you to any changes to matching samples. Use an observer query when you want to be notified about changes to the store. You can register observer queries for background delivery. For more information, see
Anchored object query. In addition to returning the current snapshot of modified data, an anchored object query can act as a long-running query. If enabled, it continues to run in the background, providing updates as matching samples are added to or removed from the store. Unlike the observer query, these updates include a list of items that have been added or removed; however, anchored object queries cannot be registered for background delivery. For more information, see
Statistics collection query. In addition to calculating the current snapshot of statistical collections, this query can act as a long-running query. If matching samples are added to or removed from the store, this query recalculates the statistics collections, and updates your app. Statistics collection queries cannot be registered for background delivery. For more information, see
Activity summary query. In addition to calculating the current snapshot of the user’s activity summary, this query can act as a long-running query. If the user’s activity summary data changes, this query recalculates the activity summary, and updates your app. Activity summary queries cannot be registered for background delivery. For more information, see
Units and Quantities
HKUnit class provides the representation for a single unit. It supports a wide range of metric and imperial units, as well as both simple and complex units. A simple unit represents a single measurement, such as meters, pounds, or seconds. A complex unit combines one or more simple units using mathematical operations, such as meters per second (m/s) or pounds per square foot (lb/ft2).
In addition to convenience methods for creating all the simple units supported by HealthKit,
HKUnit provides the mathematical operations needed to build complex units. You can also create complex units directly using properly formatted unit strings.
For more information on units, see
HKQuantity class stores a value for a given unit. You can then request the value in any compatible units, letting your app easily translate values between units.
For more information on quantities, see
You can use
MeasurementFormatter to localize quantities such as length, mass, and energy. For other quantities, you need to perform the conversions and localize the data yourself.
The HealthKit store is thread-safe, and most HealthKit objects are immutable. In general, you can use HealthKit safely in a multithreaded environment.
For more information about multithreading and concurrent programming, see Concurrency Programming Guide.
Adding Digital Signatures
Devices can digitally sign the samples they create, letting other apps validate the samples and verify that they have not been altered. To facilitate this, HealthKit provides the digital signature metadata key,
HKMetadataKeyDigitalSignature. Use this key to store a digitally signed copy of the sample record. The signature is generated by the device (which should be tamper resistant, because it stores the private signature key). This allows a data consumer to check the signature against a known public key for that device to verify that the record data has not been altered. Because each record is signed individually, storage overhead is on the order of 1 KB per record. Thus, this metadata signature item is intended for records where the sample rate is no more than a few times per day. Higher sample rates will require signatures applied to coalesced groups of samples, which is beyond the scope of this document.
Typically, a private key would be provisioned to a tamper resistant measurement device at manufacture time. (Any policies or mechanisms for private key reprovisioning or certificate updating are outside the scope of this document). The corresponding public key would be published by the device manufacturer, for example, on their web page. For each sample, the device would communicate the sample record as well as the signature to an iOS app, which would store both items in the HealthKit database. Note that the private-public key pair is used for digital signing to provide data integrity, not for encryption. The actual values in the data record are cleartext.
The format used for the digital signature is the Cryptographic Message Syntax (CMS) specified in IETF RFC 5652. The signature is encoded using ASN.1 with Distinguished Encoding Rules (DER). The message digest used should be SHA256, and the signature cipher should be FIPS PUB 186-4 Digital Signature Standard Elliptic Curve P-256. This will ensure both strength and efficiency. In addition, the entire signature should be base64 encoded so that it can be stored in the HealthKit
NSString metadata object.
The signature should be of the ASN.1 Signed-data Content Type:
where SignerInfo Type is:
The digest and signature algorithms are as noted above. Optional items have been left out. The SignerIdentifier is used to retrieve the proper public key for signature verification.
The EncapsulatedContentInfo should be a copy of the relevant items from the sample record generated by the device. This copy should be encoded using ASN.1 DER, and should contain at least a sample timestamp and sample value. The record data is copied inside the signature in order to have a stable, well-defined binary encoding (ASN.1 DER) of the data, which is necessary to produce a verifiable signature. A plist structure (key-value pairs) which is ASN.1 encoded should be sufficient for most record types. (See “Encoding plist structures with ASN.1 DER”).
Benefits of Adopting HealthKit
Health and fitness apps gain several concrete benefits from adopting HealthKit. Specifically, HealthKit:
Separates data collection, data processing, and socialization. Creating the modern health and fitness experience involves many different facets, such as collecting and analyzing data, providing actionable information and useful visualizations to the user, and fostering a social community. HealthKit allows you to focus on implementing only the aspects you are most interested in, leaving the other tasks to more specialized apps.
This separation of responsibility lets users take a mix-and-match approach by selecting their favorite weight tracking app, step counting app, and health challenge app, with each app calibrated to their needs. However, because HealthKit apps can freely exchange data (with user permission) the combined suite provides a better experience than any single app could on its own.
For example, a group of friends could decide to join a daily step-count challenge. Each person could use his or her preferred hardware device or app to track the steps, but they could all still use the same social app for the challenge.
Enables automatic data-sharing between apps. For developers, you no longer need to download APIs and write custom code to share with each app. As new HealthKit apps become available, they can begin sharing automatically through the HealthKit store.
Users don’t need to manually set up the connections between their apps or import and export their data. Importantly, users still control which apps can read and write data to the HealthKit store—and which data each app has access to. However, as soon as the user grants permission, apps can freely and frictionlessly access each other’s data.
Provides a richer set of data and a greater sense of context. By accessing a wider range of data, each app gets a more complete view of the user’s health and fitness needs. In many cases, an app can modify its metrics or advice based on the additional information from the HealthKit store. For example, a training app could suggest a post-workout snack based not only on the number of calories burned but also on the type and amount of food the user has eaten so far that day.
Fosters a greater ecosystem. By sharing the data, apps becoming part of a larger ecosystem, increasing the visibility and utility of your app. More importantly, HealthKit lets your app collaborate with other apps that the user already owns and loves. If they cannot share data with your app, they may decide to look for a solution elsewhere.