HealthKit is Apple's framework to centralize the data storage of personal health information. Hear about the latest enhancements to the framework, supporting new types of data, efficiently deleting objects, and integrating HealthKit into your Apple Watch app.
SHANNON TAN: Hello, everyone, welcome to What's New
in HealthKit, this is a great opportunity for you to learn
about the new things we have in store
for you in the SDK this year.
My name is Shannon Tan.
I'm an iOS engineer, and I'll be joined up here in a little while
by my colleague Allen Shortlidge.
We are so excited to help you build impactful applications
that will help millions of people be more healthy
and live better lives.
Let's start with a roadmap of our talk.
Today we will be talking about several different things.
We will go over HealthKit quickly.
We will talk about the unit preferences API introduced
in iOS 8.2.
We will talk about the diatribes iOS 9,
which will allow whole new aspects
of HealthKit-supported software.
Next, Allen will come up and talk about data sources,
deletions, and Workout sessions.
Finally we will finish with a WatchKit demo.
Let's talk about some HealthKit background.
Right now, personal health is an extremely exciting area.
There are a lot of apps in the App Store that are focused
on helping our users get and stay healthy,
and devices like activity trackers
and smartwatches are recording large amount
of extremely personal and relevant data.
HealthKit is a framework that makes it easier to store
and retrieve this information.
It provides a rich set of APIs to save health and fitness data
and share between applications while maintaining security
with extensive privacy settings and encrypted databases.
What does this mean for you as an app developer?
It means when you use HealthKit you can skip writing custom code
to share, store, and sync data and instead focus on features
that are core to your app experience while being part
of a greater ecosystem.
Finally, with HealthKit comes a Health app,
which provides a general view into HealthKit.
In iOS 9 we have added more views to allow to make it easier
for users to store, summarize, and correlate their data.
Let's talk about the data types
which enable these great Health applications.
Currently in HealthKit there are a lot of data types
which cover a wide array of aspects of personal health.
We try to make types that are as expansive
and impactful as possible.
One common question is, How does Apple prioritize what data types
to add given limited development time?
Our highest priority consideration is the existence
For example, there are Bluetooth scales
that automatically track weights and Sleeptrackers
that measure your sleep activities.
We find the possibility
of automatic quantified health data syncing to HealthKit
on your device to be powerful.
We also add data types based on existence of software,
whether there are popular apps that already exist
to create experience around that data type.
Finally, we consider customer and developer feedback.
To support our discussion about data types,
let's look at how they are structured.
Every object in HealthKit has a type,
and every type inherits an HK object type.
Characteristic types are types that don't change over time,
like blood type or date of birth.
Types that do change over time are sample types,
and we'll talk about two.
Quantity samples have quantity and unit, like weight.
Category samples can be enumerated
into several different values, like sleep analysis.
You can be in one of several sleep states.
Of course, this is a review of already-introduced information.
If you would like to learn more
about how HealthKit is structured,
we recommend you take a look at last year's talk,
So I mentioned that quantity samples have a quantity
I would like to take time now
to discuss the new unit preferences API.
Although this API isn't new in iOS 9, it was introduced
since our last talk in iOS 8.2.
So we would like to cover it now.
You might have noticed in iOS 8.2
that there was a new unit pane in the Health app.
Units are shown based on the region and locale of a user;
however, the user can enter this row and override
that default setting with their own unit preference.
In iOS 8.2, there is a new class extension on the HK Health Store
that you can use to find this unit preference.
We recommend you do this so that the unit you show
in your app UI will match what the user prefers
to see in Apple Health.
Finally, there is a new notification
that fires whenever this unit preference changes.
Now that we have discussed the units and reviewed data types
in HealthKit, let's talk about the new data types available
in iOS 9, the first one is water intake.
I'm sure we all know someone who lugs
around a gigantic water bottle and when asked,
explains that daily hydration is important to well-being
and it's probably bad for you to be thirsty all of the time.
There are a lot of apps in the App Store that gently nudge you
to increase water intake and even some devices and sensors
like Bluetooth water bottles that track your water intake.
A lot of people want to make sure they drink the recommended
eight 8-ounce glasses, or two liters, of water a day,
or more if they're intensely exercising or if it's a hot day
and they're at risk of dehydration.
So we have added new quantity type
in HealthKit called Dietary Water.
Its unit is a volume.
Like its name implies, this type can also track water intake
that occurs through food.
The next type is UV Exposure.
UV radiation is present in sunlight and it has harms
and benefits to human health.
It can stimulate the production of vitamin D,
and it can improve mood and well-being.
However, overexposure also has negative effects.
It can have negative effects like sunburn
or long-term effects like skin damage or cataracts.
If you spend time in the sun, it may be useful to know
when you are most at risk for sun damage.
There are also nifty devices
that track a person's exposure to UV rays.
And for apps and sensors that do so,
we're adding a new quantity type called UV Exposure.
Its value is a scalar.
It represents the UV index from 0 to 12,
from least to most dangerous.
Of course, UV exposure isn't a perfect way
to measure your risk of sun damage.
It could depend on the clothing you are wearing,
the sunscreen you have on, or the skin type you have.
For the last purpose we have added a new characteristic type
in HealthKit called the Fitzpatrick Skin Type.
This represents the skin type of an individual based
on the Fitzpatrick scale, which is based on the degree
of burning or tanning.
The emogis in iOS 8.3 are based on the Fitzpatrick scale.
All the way on the left is type 1,
which represents very pale skin that burns quite easily.
And all the way on the right is dark brown or black skin,
which never burns and tans profusely.
Because the Fitzpatrick Skin Type is a characteristic type,
it behaves differently from a category
or a quantity sample you might be used to.
It's accessed directly against the Health Store,
and it returns a simple wrapper around an enumeration.
Now, I'd like to talk to you about a whole new group
of data types we are adding under the category
of reproductive health.
So when we think about quantified health we think
about technologically driven items
like activity trackers and smartwatches.
We think about HealthKit syncing workouts,
or maybe a food diary automatically logging nutrition.
But reproductive health is a major component of health.
For many women who track their health data, nothing has been
as exciting or revealing as tracking their menstrual cycles,
and for many couples who are trying to conceive
and for many couples who are trying not to conceive,
monitoring fertile times and understanding hormonal changes
or irregularities is critical information.
It might seem strange to talk about data that is
so sensitive and so intimate.
Yet when we talk about technology improving lives,
this is vital, revealing, and insightful information.
It helps women understand and be more aware of their bodies
and to be in control of their health.
It helps and has helped millions
of people make informed decisions
about their fertility and family planning.
Apps that track cycles in fertility are some
of the most popular in the Health
and Fitness category in the App Store.
This was the number one developer request for HealthKit.
We are so excited to be adding support for these apps in iOS 9.
So there are many factors to reproductive health,
and we starting by adding six new types.
These are meant to be open, so they may be useful
for people trying to get pregnant,
trying to not get pregnant, or simply people wishing
to have a full and more complete picture of their health.
The first type is Basal Body Temperature,
and for each type we will be adding a dashboard graphic
to show you how we are visualizing this data
in Apple Health.
Basal body temperature is the temperature of your body
at rest, which typically is measured early in the morning.
It follows a biphasic path
where your temperature increases slightly after ovulation.
People often track their basal body temperature for months
at a time so they can get a pattern to their cycle
and anticipate that the next time around.
It's often measured with a pencil and paper.
It's a time-honored way to track ovulation.
Another popular way to track
or to monitor fertility is cervical mucous quality.
As opposed to the change in basal body temperature,
the change in CM occurs slightly before ovulation.
In HealthKit, this is a category sample,
which lists the generally medically accepted CM states.
The next type we're adding is Ovulation Test Results.
In females, an acute rise
in luteinizing hormone triggers ovulation.
A user can buy a home test kit and LH test strips
to measure this LH surge.
In HealthKit, this category sample measures the result
of such a test, and it can be positive or negative.
Menstruation is an extremely important measure of health.
Doctors often ask women when the date of their last period was
and about the regularity of their cycle.
Apps that help people track this are extremely popular
Here in HealthKit, we are adding it as a category sample.
We are also adding a new metadata key,
Menstrual Cycle Starts.
Because the date of your last period and regularity
of a cycle is medically important information,
we want to make it easier for apps to easily calculate this.
We ask that all clients record this Boolean metadata key,
and if we don't see it we will throw an exception.
Let's review metadata.
Metadata is a dictionary that gives additional information
about the HealthKit object
that helps you extend a given object type
and add app-specific information to HealthKit.
The keys to the dictionary are strings that you can create
or are that are Apple predefined keys.
Predefined keys facilitate sharing
between different applications.
Here we are creating a metadata dictionary
that has important information.
And we are putting the sample with the appropriate type
of value and passing in that metadata
as we're creating the sample before finally saving it
The next two types will be category samples,
but unlike existing category samples in HealthKit,
they will only have a single value,
HK Category Value Not Applicable.
These category samples have dates, metadata,
and other attributes, but they cannot be enumerated
into multiple values.
So the first of these types is vaginal spotting.
It refers to light bleeding that occurs outside
of the menstruation period.
So it's separate from menstruation.
The second type we're adding is sexual activity.
Sexual activity is relevant and important
in many fertility-tracking applications.
And we like to add support for it in HealthKit.
We are adding a new optional predefined metadata key,
Sexual Activity Protection Use.
This can refer to protection against STIs
or protection against pregnancy.
So let's summarize.
We just talked about the new data types we are adding
in iOS 9, Water Intake, UV Exposure,
and Fitzpatrick Skin Type,
and six new reproductive health types.
We look forward to seeing the new and innovative ways
that you will be using these data types
in your apps and devices.
Now, I will hand it over to Allen
to talk about data sources.
ALLEN SHORTLIDGE: Thank you, Shannon.
Hi, my name is Allen, I'm a software developer
on the HealthKit team at Apple.
We just heard Shannon discuss the new types
of data you can store in HealthKit in iOS 9,
and now I would like to tell you a little bit
about the new things that you can do with HealthKit in iOS 9.
The first set of changes I will be discussing have
to do with sources of data.
HealthKit can store data from a variety of sources.
Samples may be pulled automatically
from the Motion code processor in the user's iPhone
or from a connected Bluetooth heart rate monitor.
They may also come from manually entered samples
in the Health app or saved by applications create
by developers like you.
Knowing where the data in HealthKit came
from can be important, especially if you are using
that data for medical or research purposes.
So how do you tell where data in HealthKit came from?
Well, the HK object class is the root class for all data stored
in HealthKit, and in iOS 8 it had two properties related
to the source of that data.
The first is the Source property.
And it represents which application saved that object.
The second property is Metadata.
Developers often use metadata to store information
about external devices that created objects.
This information can be things like the name
of the external device or the manufacturer.
In iOS 9, we are introducing two new properties
that give you richer information
about where the object came from.
The first of these new properties is the Source
Revision property, and it replaces the Source property.
In addition to representing the application
that created the sample, it also carries the version of the app
that saved the object.
The second property is the Device property,
and it returns an object that represents the external device
that created the object.
It's intended to replace metadata related
to external devices.
Let's take a quick look at the HK Source Revision class.
It just has two properties, the source, which, again,
represents -- oops sorry.
Which represents the application that saves the data,
and then it also includes a version string.
When you save an object to HealthKit,
HealthKit will automatically assign an HK source revision
The version string comes from the bundle version entry
in your app's Info.plist.
Objects that were saved to HealthKit prior
to iOS 9 will have a nil version string.
Now, let's talk about HK Device.
HK Device is a class that includes a number of strings
that represent different aspects of a hardware device
such as its name, manufacturer, version information, and so on.
When you create a device, you will want to provide as many
of the applicable properties as possible to give your users
and other applications the richest information possible
about where the object came from.
If your app saves objects that were generated by the sensors
that are built into the device that your app is running on,
then you can use the local device class method on HK Device
to get a device representing the device
that your app is running on.
So let's take a look at how you would save a sample
with a device.
First, you will create a device with all
of the applicable properties.
Next, instantiate a sample using one
of the HK sample subclass initializer methods
that takes a device.
Then finally, you can save that object to HealthKit just
as you would have previously.
Querying for objects that come
from a particular source revision or device is easy too.
You can use one of the new predicate convenience methods
exposed on HK Query in iOS 9.
Here is an example of querying for objects that were saved
by a previous version of our application.
First, we are creating a source revision with a default source
and a 1.0 version string.
Next, we are instantiating a predicate
that matches all samples that have that source revision.
Then finally, we will execute an HK sample query,
and it will return to us all of the objects that were created
by version 1 of our application.
So now that we have talked about new ways to save objects
to HealthKit, let's talk a little bit
about deleting objects.
In iOS 8, there was one way to delete objects, and that was
with the Delete Object method on HK Health Store.
It takes a single object to delete, which is simple,
but also a little inconvenient if you need to delete more
than one sample at once.
So we are introducing two new convenient ways
to delete objects.
The first is a method on HK Health Store
that takes an array of objects to delete.
You can use this whenever you have previously queried
for a set of samples and you want to delete them all at once.
For example, you might want to migrate samples that were saved
by a previous version of your app
to use HK Device instead of metadata.
Once you have saved new copies of your previous objects,
you could delete all of the old ones using Delete Objects.
The second new method that we are exposing is Delete Objects
Of Type with a predicate.
So it will delete all of the objects
that match a given predicate.
This is efficient because you don't have to query
for the objects before you delete them.
So it's not always the case that you just want to delete objects.
Sometimes you also want to find out about
when objects were deleted.
Maybe the user has deleted it or another application.
If your app synchronizes with HealthKit,
ideally you would remove an object
from your database whenever that object is removed
from HealthKit's database.
Within iOS 8, there was no straightforward way
to accomplish this.
We are introducing a new way to query for deleted objects
in iOS 9 using the HK Anchored Object Query class.
HK Anchored Object Query has a new initializer
with a results handler block that has parameters
for both new sample and deleted samples.
Now, when you execute this query, HealthKit will return
to you all the samples that have either been created or deleted
that match your predicate
since the last time you ran an anchored object query,
which is indicated by the anchor you provide.
Deleted objects are represented by instances
of the HK Deleted Object class, which just carries the UID
of the object that was deleted.
To save space, deleted objects are only stored in HealthKit
for a limited amount of time before they are
That means if you have functionality that depends
on querying for deleted objects, you should register
for background updates to guarantee
that your app will be launched in response to deletions.
You can use the existing Enable Background Delivery
For Type method that exists in iOS 8 to be launched in response
to deletions and sample creations in iOS 9.
Now, we are going to return briefly
to HK Anchored Object Query to talk
about a second new addition we have made to the class in iOS 9.
That's the Update Handler property.
When provided, this block will be called
after your results handler whenever there are more samples
that have been created or deleted
that match your predicate.
An HK anchored object query
that has an update handler will continue to run indefinitely
until you stop it explicitly with Stop Query
on an HK Health Store.
As you will see later in this presentation,
this can be an efficient way to process a stream
of data from HealthKit.
For instance, you might want
to display the user's latest heart rate reading
You can use an update handler to accomplish this.
As you may be aware, Apple recently released a new piece
of hardware, which can detect the wearer's heart rate.
Wouldn't it be cool if you could run this query directly
on that device?
Well, it turns out you can.
So in addition to making improvements for HealthKit
on iOS 9 this year, we are also bringing the framework
to WatchKit apps.
So HealthKit on watchOS is a lot like HealthKit on iOS.
Almost all of the HealthKit APIs that you're familiar
with are available on watchOS also.
You can store and retrieve health data with all
of the same queries and methods that you are used to.
However, because performance is incredibly important
on our new platform, only a limited amount
of historical HealthKit data is available on the Watch.
We are also introducing brand-new workout APIs
that will help you record workouts on the Watch.
Finally, data saved to HealthKit
on the Watch will sync automatically
to the phone that the user has.
When your app saves a workout on Apple Watch, the energy burned
by the user gets counted in their activity rings.
Your users will love getting credit for the exercise
that they do while wearing the Watch and using your app.
As you can see in these screenshots,
workouts that you save will show up in the Daily Summary
and the Activity app on iOS.
Now, before I discuss workouts more, I would like to turn
to privacy for a second.
We take the privacy of user's HealthKit data seriously,
so naturally we protect it on the Watch just as we do on iOS.
We will need to request access
to use the user's HealthKit data.
When your app requests authorization,
a prompt will appear on both the Watch and the user's phone
to authorize your app for access.
So if your phone application is authorized to store
and retrieve distance samples, let's say,
then your Watch app also will be authorized to store
and retrieve distance samples.
So once you have a WatchKit app that's authorized
to use HealthKit data, one thing you might want
to do is record a workout.
We are introducing the brand-new HK Workout Session class
to facilitate this.
With HK Workout Session, you can specify a type
of activity the user is performing,
and this information helps Apple Watch more accurately record the
While in session, your app stays in the foreground,
so whenever the user raises their wrist
to check the progress of the workout,
your app will be front and center.
Note that only one workout session will be running
at any given time.
So if the user starts another workout in another application,
then your workout session will end.
Let's look at HK Workout Session.
You instantiate a workout session
with an activity type and a location type.
The location type indicates whether the activity is taking
place indoors or outdoors.
You can also set a delegate.
This allows you to be informed of changes
to the state of the workout.
So the HK Workout Session delegate protocol has
The first of these is called whenever the state
of the workout changes.
For instance, from Not Started to Running or Running to Ended.
It's a good opportunity to note the start and end date
of the workout and also start
or stop any data queries that you might have.
The second method is called whenever there is an error.
It will be called in addition to the first method,
and it indicates that your workout session ended.
Starting and stopping workout sessions is really easy.
You just call Start Workout Session or Stop Workout Session
on an HK Health Store.
So now I'd like to give you a quick demonstration of how
to build a WatchKit app using these new APIs.
So I have built a simple WatchKit application,
and I would like to give you a tour of that app now.
It allows the user to specify an activity
that they are performing, like running.
I will choose running.
Once they have chosen an activity type,
they will next choose a location type.
Outdoors or indoors.
I will choose outdoors, and this is the in-session view,
and it will show a couple of metrics about the workout.
So nothing is happening in this session view
because we haven't hooked it up to HealthKit yet.
Let's do that now.
Here in Xcode, we are looking
at my activity interface controller.
This is the first view we just saw where the user chose
when activity they were performing.
This is a good opportunity for me to request authorization
to access HealthKit data.
So I'm going to do that right here in the awake --
I'm sorry, Will Activate method.
The first thing I have done is instantiate a set
of types I want to share which just includes the workout type,
and then next, I have a set of types that I would like to read
from HealthKit, like active energy burned, distance cycling,
distance walking and running, and the heart rate of the user.
Finally, we just call and request authorization
to share types just like you would on iOS.
Now, we also need to implement something
in our companion application to finish this request.
So I'm in the app delegate of my companion app
and I will implement a new UI application delegate method.
Application should request health authorization.
Here all I'm doing is calling handle authorization
for extension with completion,
which will prompt the user to authorize my app.
Let's see this in action now.
So as you can see, the user has been prompted on both the Watch
and the phone to open your app and authorize the app.
Here is the familiar health authorization sheet.
I will approve the app to access everything it wants to,
and hit Allow.
Now, we are authorized to use HealthKit data.
So the next thing we need to do is start a workout session
when the user taps Start.
I have a Workout Session Manager class here,
and that's what is responsible
for managing my interaction with HealthKit.
It's a bit of a big class, but we are going
to implement just a few parts of it.
The Start Workout method is called right here
when we hit the Start button.
So I will want to start a workout session
which I have instantiated previously in my constructor.
All we are doing is calling Start Workout Session
on an HK Health Store with that workout session.
Now, we need to implement the workout session delegate
protocol so that we can be informed of changes
to the state of the workout.
So as this is called on a background cue,
I'm dispatching back to the main queue before handling the
If the state of the session changed to Running,
I will call my Workout Did Start method, and if it changes
to Ended, I will call Workout Did End.
So let's go down to Workout Did Start.
One of the things we will need to do is start some queries
for HealthKit data to display in the workout.
One of those metrics is distance.
So I need a query for gathering distance data from HealthKit
and accumulating it as the workout session progresses.
I'm going to create a helper method that will create
that query right here, and we are going
to use HK Anchored Object Query with an update handler.
So I have written Create Streaming Distance Query,
and it takes a workout start date.
The first thing we do is create a predicate,
which matches all queries that, sorry, matches all samples
that have a start date after the workout start date.
Next, I have instantiated an HK anchored object query
with a results handler
that calls my Add Distance Samples method.
Add Distance Samples is implemented right here.
It dispatches back to the main cue
and then it adds the new distance sample
to my running total of distance and it also adds that sample
to an array of samples that I'm accumulating
over the course of the workout.
So, again, in the results handler we call Add Distance
Samples, and then in our update handler,
we do exactly the same thing,
and finally we return that distance query.
So now that we have that available to us,
let's use it in Workout Did Start.
Workout Did Start notes the start date of the workout,
and then it creates queries for streaming distance,
active energy, and heart rate.
It executes all of the queries that we created,
and then it informs the UI that the workout started.
So let's take a look at how this works now.
So I will choose running again.
An outdoor run.
And as you can see, the timer is increasing,
and I'm also accumulating some simulated distance samples,
and some calorie samples will show up in a little bit.
So the user can see their distance, calories,
and heart rate right here in the app.
The last thing that we want to enable the user to do is
to stop and save the workout.
I have a Force Touch menu that just has a single Save button
that the user will tap when the workout stops.
We haven't implemented this yet,
so the workout is still continuing though.
So now let's implement that.
So I have a Stop Workout And Save method that's called
by the UI whenever the user taps that Force Touch menu button.
I will stop the workout session here.
And I do that just by calling Stop Workout Session.
Now, we need to handle that state change to the ended state.
We are calling Workout Did End in response to that.
So here, as you might imagine, we need to stop our queries
and then save the workout.
So we will note the end date of the workout.
We will stop all of our queries.
We will inform the UI that the workout stopped,
and then we will save the workout.
Saving the workout to HealthKit is pretty simple, too.
The first thing I have done is unwrap the optional start
and end dates that I noted
in Workout Did Start and Workout Did End.
I am using Swift's new guard statement
to return early if those are nil.
Next, we instantiate a workout with the activity type
that the user performs, the start and end date,
and the total active energy burned and distance.
I'm also creating an array with all of the samples
that I accumulated over the course of the workout,
because we want to associate these samples with it
after we save the workout.
Next, I will save the workout to HealthKit,
and once that's complete, I will add samples to that workout.
So let's take a look at that now.
So I'm choosing running again, outdoor run,
my workout is progressing.
Once we have got a few metrics here, I'm going to save it.
And I will save it.
And the workout is finished.
So now that we have saved that workout to HealthKit,
let's see if we can get it to show up in our companion app.
There is our three-calorie workout right there.
It was a lot of work.
Okay. Let's recap what we did in the demo just now.
First, we requested authorization
to access the user's HealthKit data.
Next, we used HK Workout Session to record the workout
and we streamed samples
from HealthKit using HK Anchored Object Query.
Finally we saved the HK workout to HealthKit
and associated samples with it.
So that's what's new in HealthKit in iOS 9.
We started today by covering the unit preference API,
which allows you to display HealthKit data
in your app using the units that the user prefers.
Next, we covered new data types that you can store in HealthKit
such as Water Intake, UV Exposure,
and information related to reproductive health.
Next, we talked about source revisions and devices,
which give you a richer picture of where the data
in HealthKit comes from.
We also covered new ways to delete samples
and query for deleted samples.
And finally, we discussed the HK Workout Session API
and showed you how to build a WatchKit app that uses it.
We think you will love the improvements we made
to HealthKit in iOS 9 and we can't wait
to see what you build with it.
For more information, you can visit the developer
documentation at developer.apple.com/healthKit
or contact technical support.
You can make a general query to firstname.lastname@example.org.
So thanks, and enjoy the rest of the conference.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.