Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
>> 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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
of hardware.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
Introducing HealthKit.
So I mentioned that quantity
samples have a quantity
and unit.
I would like to take time now
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
[ Applause ]
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
and varied.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
to HealthKit.
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, I will hand
it over to Allen
to talk about data sources.
[ Applause ]
>> 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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
to it.
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
expunged permanently.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
from HealthKit.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
[ Applause ]
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
user's activity.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
two methods.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
state change.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
[ Applause ]
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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 healthkit@apple.com.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can make a general query
to healthkit@apple.com.
So thanks, and enjoy the
rest of the conference.
[ Applause ]