WWDC2019 Session 217

Transcript

[ Music ]
[ Cheering and Applause ]
>> Hello, everyone, and welcome
to the session ResearchKit and
CareKit reimagined.
My name is Srinath.
And I'm an engineer on the Help
Team.
Now, we have a lot of topics
that we want to cover today.
So let's jump right into it by
looking at the overall flow for
today's session.
As always, we'll get started
with community updates.
We'll then talk about updates we
have made to the ResearchKit
framework.
And then we have some really
exciting news that we want to
share about the CareKit
framework.
Jumping into community updates,
we wanted to highlight some apps
that have been released or
updated in the past year that
leverage the ResearchKit and
CareKit frameworks.
One such example is the
FocalView app, which was
released by Novartis.
And it focuses on running
ophthalmic clinical trials on a
digital platform.
The other notable example is the
FDA MyStudies app.
Now, this app is the
patient-facing part of a
compliant platform that can be
used for clinical trials or
real-world evidence studies.
The FDA went on to Open Source
the MyStudies app for other
organizations to rebrand,
publish, and use.
Now this year, apart from
talking about apps, we also
wanted to talk about
publications.
Now for context, the ResearchKit
and CareKit frameworks were
announced roughly three to four
years back.
And we have reached a point
where we are starting to see an
influx of publications coming
from studies that have been
running for the past few years.
Most of these publications talk
about how successful a
mobile-based study design has
been towards things like
participant enrollment, the
ability to recruit diverse
participants from both a
geographic and demographic
standpoint, as well as the
overall reduction in
per-participant cost as more
participants continue to enroll.
Now let's take a look at a few
of these publications.
The Pride Study talks about how
successful they were in
recruiting and engaging with a
large number of underrepresented
participants for clinical
research.
The Healthy Pregnancy study
talks about low attrition rates
and how they were able to get
their participants to fill out
mobile-based surveys and
questionnaires at a regular
cadence.
The Personal Touch publication
is interesting, because this
publication went out in May
2019.
And we got to know about it
roughly a week back when one of
the authors submitted a poll
request on GitHub to contribute
some of the active tasks that
they had built to support this
publication back into the
framework so that the rest of
the community can leverage that
as well.
And on that note, all of our
health frameworks --
ResearchKit, CareKit, and
HealthKit -- were introduced to
empower the developers to create
some amazing research and care
apps.
On top of that, we also have
some really powerful devices
that have sensors, starting with
accelerometer and gyroscope, all
the way to electrodes that
allows your users to take an EKG
reading.
And be continued to be amazed by
the work that our community of
developers, researchers, and
health professionals are able to
accomplish by leveraging our
products and platforms.
But every year, we still receive
a lot of emails asking about a
variety of questions, like,
"What is ResearchKit and
CareKit?
Or how do I create a research or
a care app?"
And we also received proposals
from research institutions for
device grant requests, which is
why this year, we are currently
working on a couple of
initiatives.
And right now, I just want to
give a brief preview about these
initiatives.
The first one is an
investigator's support program
that we are piloting.
We are currently developing this
program.
And this will be live later this
year.
Now, this will be a Limited
Apple Watch Grant Program that
will have a very simple and easy
proposal submission process.
We will prioritize studies that
advance science and help people
to lead healthier lives by
uniquely leveraging our
ecosystem.
The second initiative that we
want to preview right now is a
redesigned website.
Now, this website will contain
clear information for everyone
who wants to learn more about
the ResearchKit and CareKit
frameworks.
You will also be able to gather
insights from other researchers
and developers who are
leveraging these frameworks to
build some amazing research and
care apps.
This website will also have a
lot more information about the
investigator support program.
And both the website and the
investigator support program
itself will be live in Fall of
2019.
And we are really excited about
this.
And now, let's switch gears and
talk about updates that we have
made to the ResearchKit
framework.
We want to cover two main
topics, UI updates, and active
tasks.
Let's get started with UI
updates.
This year, our main focus has
been around refining the user
experience, around answering
survey questionnaires.
Because we realized that some of
the validated medical
questionnaires and onboarding
flows can be extremely long.
So you can see here that we have
updated the card styling for you
to provide more contextual
information to your users.
This includes an intra step
progress indicator, as well as a
Learn More button.
Now this button can be used for
situations where your questions
or answer choices contain
terminologies but just not quite
self-explanatory.
So in this example, if your
users are unaware of what
narcolepsy actually means, they
can simply tap on the Learn More
button to pull up a sheet that
gives them a lot of information
about the question and the
answer choices themselves.
Now you'll notice that we have
added a Top Content Image view.
And this styling will now be
consistent throughout
ResearchKit, so all of our steps
now have the ability to display
rich media content via the Top
Content image view.
And if you scroll further down,
we have added a new object of
type body items, which can be
used to compose lists that will
be automatically formatted for
you.
And now let's take a look at how
you can incorporate these
changes into your existing apps.
So the first thing that you want
to do is create an instance of
ORK learnMoreStep with a unique
identifier.
All of our steps now have this
image property, which will
display as the top content image
view.
You can also customize other
properties, like title and text.
The other thing that you need to
do is create an instance of
ORKBodyItem.
And it accepts the following
parameters, like text, detailed
text, and a style.
You can choose between bullet
point images and just plain
text.
Now all of our steps accept an
array of body items.
So let's assign this body item
to the learnMoreStep.
The next thing that you would
want to do is create an instance
of learnMoreItem and bypassing
in the step.
So this is the object that
essentially creates the Detail
Disclosure button on the screen.
We also have another initializer
which accepts text.
So that one will be displayed as
a hyperlink in your step.
We have also added another
initializer to ORK form items in
order to help you customize the
section headers, which allows
you to group multiple form items
under the same section.
Now this accepts properties like
sectionTitle, detailText, the
learnMoreItem, and the toggle to
indicate whether or not you want
to display the intra step
progress indicator.
And now that you have
incorporated these changes into
your apps, your users can make
an informed decision before
answering any of your questions.
Now let's move on to active
tasks.
Now similar to last year, this
year, we will be focusing on our
three main areas of health --
vision, hearing, and speech.
Now when it comes to measuring
visual health, there are two key
metrics that are considered as
the gold standard, visual acuity
and contrast sensitivity.
Visual acuity is essentially
your ability to distinguish and
identify an object along with
its features.
It comes in two stimulis.
One is the Landolt C, and the
other one is a Snellen or
Tumbling E.
Now our first active task in the
visual acuity space is a
contribution by Novartis from
their FocalView app.
Now, this app essentially
requests the user to align the
outer dial with the opening in
the letter C.
Now the Landolt C stimuli
remains in fixed contrast but
keeps decreasing in size and
pops up in random orientations.
Once a user completes this task,
the developer will receive a
visual acuity rating score for
that user.
To incorporate this in your app,
you create an instance of
ORKLandoltCStep with a unique
identifier.
You then set the testType to be
acuity.
And then as always, you can
create an ordered task by
passing in an array of steps,
then pass the task to create a
TaskViewController, which you
can present within your app.
Our second active task in the
visual acuity space leverages
Tumbling E as the stimuli.
Now as part of this task, the
user will be expected to swipe
into the direction of the arms
of the letter E.
Now similar to Landolt C, the
Tumbling E will remain fixed in
contrast, will decrease in size,
and pop up in random
orientation.
But the interesting piece here
is that the testing distance,
along with the size of the
stimuli, is controlled by the
TrueDepth camera.
And once the user completes this
task, you will receive a lot
more value, where MAR stands for
Minimum Angle of Resolution.
To incorporate this in your app,
you create an instance of
ORKTumblingEStep with a unique
identifier.
You can also specify the minimum
and maximum viewing distance
that is specific to your trial.
And same as always, you create
an OrderedTask, pass that to the
ViewController, and present it.
Now let's move on to our next
big category ambition, contrast
sensitivity.
This essentially refers to your
ability to distinguish an object
from its background.
And it comes in -- so two
stimuli is most commonly used to
test for this particular
contrast sensitivity feature.
One is Landolt C, and the other
one is a Gabor Patch.
The first active task in
contrast sensitivity is once
again a contribution by Novartis
from their FocalView app.
Now, this is very much in line
with the visual acuity task.
But the key difference here is
that the Landolt C remains fixed
in size but keeps decreasing in
contrast as it is being
presented in random
orientations.
And once the user completes this
task, you will receive the
visual acuity rating score for
the user.
Adding this to your app is
exactly the same as the visual
acuity task.
The only key difference is that
you're going to toggle the test
type to be contrast sensitivity.
As part of our next task, we
will try to generate the
contrast sensitivity function
for a user by presenting them
with the stimuli known as the
Gabor Patch.
And this is what it looks like.
So you'll notice that there are
certain lines on the stimuli
that is leaning to the right,
especially the top tilt.
And in the other stimuli, you
will notice that the top tilt,
or the upward tilt, is leaning
to the left.
Now, your users will be expected
to recognize that leaning of the
tilt and select the appropriate
direction as part of the task.
Now, the Gabor Patch stimuli is
generated programmatically using
an adaptive algorithm that
varies the spatial frequency.
Now the Gabor Patch will be
displayed with random
orientations and different
positions within the screen.
And once again, the testing
distance and the size of the
stimuli itself is controlled
real time by the TrueDepth
camera.
Once the user completes this
task, the developer will be able
to use the results to generate a
sensitivity vs spatial
frequency curve for the user.
To incorporate this in your app,
you create an instance of
ORKCSFStep with a unique
identifier.
Once again, you can set the
minimum and maximum viewing
distance that is specific to
your trial.
You create an OrderedTask, pass
that to the TaskViewController,
and simply present it within
your app.
Now the contrast sensitivity
function and the Tumbling E
active task that leverage the
TrueDepth camera will be
available soon via an Apple
sample code license on
developer.apple.com.
Now let's move on to our next
category, hearing.
So last year, we announced three
new active tasks that focus on
hearing health.
We had to tone audiometry,
speech and noise, and SPL meter.
This year, we are making
across-the-board enhancements to
the algorithms.
And what's even better is that
you can now write the results of
these active tasks directly into
HealthKit.
To learn more about these new
data types, I would recommend
you to check out the HealthKit
session that's happening today
at 2:00 p.m.
Now let's move on to speech.
Last year, we introduced a
speech recognition active task.
When a user completes this task,
you will receive a bunch of
information, including the raw
audio file, the transcript, as
well as an SFTranscription
object rendered by the speech
recognition framework.
Well, this year, the Speech
Recognition team has added more
capabilities to the SF
transcription object.
So you will be able to extract
information like speaking rate
and average pause duration.
And on top of that, there's also
a new object called
SFVoiceAnalytics.
And to learn more about these,
please check out the session
titled "Advances in Speech
Recognition."
And those were our overall
updates and additions to our
expanding library of active
tasks.
Now, you might have noticed that
some of these tasks leverage
some system frameworks under the
hood.
And we want to remind you that
there are a lot of other
powerful iOS system frameworks
as part of our SDK.
And we would highly encourage
developers to leverage the true
potential of these frameworks as
you're thinking about adding new
active tasks into ResearchKit or
even if you are considering
adding novel experiences that
focus on health.
And with that, let's move on to
updates for CareKit.
Now, the CareKit framework was
introduced back in 2016 as an
Open Source framework.
And we wanted to enable the
developers to perform three main
things -- the ability to be able
to easily digitize a
prescription, the ability to
provide meaningful data and
trends to the user, and to allow
your users to easily connect
with their care providers.
And over the past few years,
we've been making incremental
updates to the framework.
And this year, I'm really
excited to announce CareKit 2.0.
And this is what it looks like.
Now you'll see that we have
completely revamped the UI for
the framework.
But what's even better is that
we have fundamentally
rearchitected and rewritten the
framework purely using Swift.
Now, that means that CareKit,
under the hood, can leverage
some of the most powerful Swift
language features, including the
newly announced combined
framework.
Now let's dive into some
details.
The CareKit framework now
comprises of two other
frameworks under the hood --
CareKit UI and CareKit Store.
CareKit UI is a separate project
inside the CareKit repository
that you can independently
compile and expose as a separate
framework.
CareKit UI is all about
pre-packaged sub classes of UI
views.
So what that essentially means
is that every single view that
you see on the screen is
available for you to leverage in
your app using CareKit UI.
And we have categorized them
into three categories or
components.
We call them tasks, charts, and
contacts.
And these are used to reflect
the functionality that each view
is supposed to serve.
Now, as I mentioned, all of the
views in CareKit UI are just
naive UI views and are
essentially sub classes of UI
views.
So I want to start off by
talking about all the views that
are available in tasks.
And there are five of them that
we want to highlight today.
Now here, you can see that we
have a view.
And since it is just a subclass
of a UI view, you can constrain
it anywhere within your app by
adding it as a sub view.
Now to create this view, all you
have to do is import CareKit UI,
create an instance of
OCKSimpleTaskView, and set some
of the parameters that are
available on this object.
It's that easy.
And now let's take a look at the
remaining four UIs that we said
are available inside the task's
component.
The next one that we want to
cover is the
OCKInstructionsTaskView.
So when you create an object of
this type, you will get a view
that looks somewhat like this.
And all you have to do is add
one additional parameter to set
the right values.
Along those same lines, the next
view that we want to talk about
is the OCKGridTaskView, which
looks somewhat like this.
Now this view is interesting
because all the check marks and
the buttons that you're seeing
here, this is standard for a
medication view.
And as part of this view, we are
essentially exposing the
collectionView to you directly.
So you could choose to set
yourself up as the delegate and
pass in whatever view you want
into the collectionView.
So you can choose to use an OCK
button.
Or you can even provide any
custom UI.
It is extremely customizable as
well.
Our next view type is an
OCKChecklistTaskView, which
looks somewhat like this.
And all the buttons that you see
on screen are now composed
inside a Stack View.
So by simply calling an
appendItem method, you'll be
able to add a new role into your
checklist as a new item.
Our final view type under the
tasks component is an
OCKSimpleLogTaskView.
It looks somewhat like this.
And it can be used for logging
random events like a headache or
nausea.
And every time the user taps on
the log button, we will show
them a timestamp of when they
logged their last event.
And the timestamps are once
again composed inside the stack
view.
So by simply calling the
appendItem method, you'll be
able to append more logs based
on the action that is generated
by the button.
Now, let's move on to our next
component, charts.
So to create a chart in CareKit
UI, you simply import CareKit
UI.
You create an instance of
OCKCartesianChartCardView and
specify a type.
You can then go on to set the
title, the text, and even the
values as part of the data
series.
And by simply toggling the type,
you'll be able to easily switch
between the different chart
types for that exact same set of
data points.
And our final component which we
want to cover today is contacts.
So you can create an instance of
OCKContactCardView and just
populate it with content.
And we will ensure that all the
constraints are applied in the
right way.
So those were our overall
updates for CareKit UI.
Our real intention here is to
continue to add more views to
each of these components and
also expand the library of
components that we have.
We think that this can be an
extremely powerful tool for
users and makes the CareKit 2.0
framework highly customizable,
because we just give you all the
new sorts of views with all the
constraints taken care of.
Now let's talk about CareKit
Store.
CareKit Store, similar to
CareKit UI, is its own project
inside the CareKit framework.
So you can compile it and export
it as a standalone framework
into your app and use it in a
completely unrelated manner.
CareKit Store is essentially a
wrapper on top of Core Data that
allows you to persist Care Plans
and react to them locally on
device within your app
containers.
And since it's a database
essentially, we have given you a
cookie cutter scheme.
And let's take a look at what
that looks like.
So the most fundamental entity
for any Care app is the patient.
Now let's take a look at how you
initialize a CareKit Store,
create a patient object, and
ingest that into the CareKit
Store.
So you start off by importing
CareKitStore as a standalone
framework.
You then create an instance of
OCKStore with a unique
identifier to create the Core
Data database within your app
container.
You then go on to create a
patient object by using one of
our convenience initializers
that accepts some basic
parameters.
You can then call the
addPatientMethod on the Store,
which asynchronously accepts the
object and ingests it into the
database.
And once that is complete, you
will get a completion callback.
And this will return a Swift
result type that you can switch
on.
Now our second key entity in our
Care Plan is the Care Plan
itself.
And every patient can have
multiple Care Plans associated
with them.
So now let's take a look at how
you can create a new Care Plan
and associate it with a
particular patient.
So as always, you create a
reference to the store.
Now one thing to note here is
that if you provide an
identifier that is already
available, we will just take an
existing store with that
identifier and return that to
you.
So then, if you don't have a
reference to the patient object,
the first thing that you need to
do is query the patient object
from the Store.
And once that query completes
asynchronously, you get a
callback.
And inside the callback, you can
go on to create a Care Plan by
providing it parameters like
identifier, the name for the
Care Plan, and most importantly,
the patient ID.
Doing this will essentially help
create the association between
the patient -- the Care Plan and
the patient itself.
And then you can call the
addCarePlan method to ingest
this new Care Plan into your
database.
Now every Care Plan can have an
array of contacts associated
with them.
Now, these could be contacts for
the primary care providers who
are associated with this
particular Care Plan.
Now, the other thing that's
interesting here is the notion
of tasks.
Now task entities are
essentially action items that
your users are requested to
perform on a daily basis as part
of their Care Plan.
And every task has an associated
schedule object with it.
Now the schedule dictates when
the user is expected to perform
a particular task.
So now let's take a look at how
you can prescribe a particular
medication to your user and
ingest that into your Care
Store.
So here, we are creating a
schedule where you need to take
your medication every day at
7:00 a.m. We are creating
another schedule element that
expects you to take the same
medication every other day at
12:00 p.m. So we are calling the
former one as breakfast dose and
the latter one as the lunch
dose.
And you can simply compose
multiple schedules together to
create one unified schedule
which you can then pass on to
the task.
So the OCKTaskObject accepts
parameters like identifier.
The title here is a Doxylamine
medication, and you can give it
the schedule object.
And you can directly add this
task into your CareKit Store.
Now, every time your user
completes a particular task, we
generate an outcome.
And every outcome has an
associated value with it.
Now let's take a look at how you
can query all the outcomes in
your database to create
meaningful data and trends that
you can surface to your users.
So here we are creating a
blanket query that will query
all elements in your database
for the past seven days.
We are then calling the
fetchInsights method on the
task.
And we are passing it the
identifier for the particular
tasks whose event you are
interested in.
So in this case, I'm only
interested in events generated
for the doxylamine medication
task.
Now, this API has two blocks
that are very interesting.
The first one is the daily
aggregator block which can be
called multiple times.
And every time, you get an array
of events for that particular
day.
And you can use this to compute
higher-order metrics.
And then you get the completion
block, which is called only
once.
And it gives you an array of
computed values that you can use
for further analysis or simply
for charting.
Now, every single entity in the
CareKit Store can have an
associated note object with it.
Now note objects are essentially
metadata.
So for example, if the care
provider decided to update the
Care Plan for some reason, and
they wanted to provide you with
free form text, you will be able
to add that to the note object.
And the other interesting thing
is that some of our key entities
are now versionable.
So when you update a medication
task, or when you update a
schedule, we will persist that
in the CareKit Store and you can
go back and forth between them.
So those were our quick updates
for the CareKit Store.
There are a lot more powerful
API's that are available in the
CareKit Store framework.
And we would recommend you to
check them out.
So now let's turn our focus to
the CareKit framework itself.
CareKit is all about bringing
synchronization all the way from
the UI level to the underlying
database.
And the way we accomplish this
is by using a synchronizer
object.
Now this object makes heavy use
of the combined framework under
the hood to propagate events
between the UI layer and the
data store layer.
Now, another key functionality
of CareKit is its modularity and
customizability.
So what I mean by that is that
the database here can either be
a CareKit Store, or it can be
any database of your preference,
as long as it conforms to our
OCKStore protocol, which will
enable the synchronizer to
interact with it seamlessly.
And the UI elements that you see
here can either come from
CareKit UI.
Or they could be even your
custom UI views, as long as you
tell us how to bind the views to
a particular object.
So now let's take a look at what
happens when a user interacts
with the UI element on the
screen.
So for this example, let's focus
on the doxylamine medication on
the top-left corner.
When the user taps on this
button, an event is propagated
to the synchronizer.
The synchronizer then forwards
the information to the
underlying data store.
And once the database
acknowledges successful receipt
of this object, the synchronizer
takes up the role of a
publisher.
And it propagates the stream to
all the UI elements that are
subscribed to that particular
stream.
And in this example, there are
only three cards that are
subscribed to updates from the
medication task.
And once the stream reaches
them, they will be able to
independently update themselves.
This is really exciting because
the UI views are acting
independently of each other.
And they're also updating in an
asynchronous manner, which can
lead to some really powerful
experiences in your care app.
Now, let's take a look at how
you can incorporate CareKit in
your app end-to-end in code.
So the first thing you do is you
import CareKit.
And doing so will automatically
import the CareKit UI and
CareKit Store frameworks.
Next, as always, you create an
instance of OKCStore.
And then you go on to create an
instance of
OCKSynchronizedStoreManager and
pass it the store.
This will allow the synchronizer
to wrap itself around the
database.
And finally, you can choose to
use one of our prepackaged
standalone view controllers.
In this example, we are
showcasing the OCKTaskListView
controller and it accepts the
storeManager assets parameter.
Doing this will essentially
establish pipelines all the way
from the UI layer to the
underlying database, and all you
have to do after that is present
the view controller, and
depending on what data you
provide to the store, you'll be
able to see a UI that looks
somewhat like this.
And similarly, you can also
leverage some of our other
prepackaged view controllers to
build out views for trends and
contacts.
So as you can see here, CareKit
2.0 makes it really easy to use
the framework.
But that's not all it's all
about.
So, right now, I want to call
Erik onstage for a demo where we
will showcase how you can build
a custom care app using CareKit
2.0.
[ Cheering and Applause ]
>> All right.
[ Cheering and Applause ]
Great. Thank you, Srinath.
Good afternoon, everybody.
My name is Erik.
I'm an engineer on the CareKit
team.
And today I have the privilege
of walking y'all through a
sample app that's going to
demonstrate some of the amazing
new features and capabilities of
CareKit 2.0.
The app that we're going to
build to that -- together today
is going to be built completely
from scratch.
And it's going to be for an
imaginary patient, an expecting
mother who is experiencing
severe symptoms of morning
sickness, namely nausea.
So the app that we're going to
make for her is going to allow
her to track her medications.
It's going to allow her to leave
a log when she feels nauseous.
And we're going to display
charts to her that allow her to
understand the correlation
between her adherence and her
symptoms.
Finally, we're going to give her
quick access to her contacts so
that she can get directions to
the office or make a call to her
doctor if she has an emergency.
Now, when we make a CareKit app,
there's two major steps that we
have to walk through.
The first is that we need to
create the Store.
And we need to populate it with
data.
So that's going to be the first
thing we tackle.
And then after that, we need to
create the UI and tell CareKit
how we want the data to be
displayed.
So we're going to hit that in
the second half.
Let's jump in.
Whoops.
All right.
So you can see here, we've got
an empty app.
This is going to be our starting
point.
Now when you're using CareKit,
the first thing you need to do
is import it.
If you don't do this, you're not
going to get far.
[Chuckles]
Once it's imported, the next
thing we need to do is create
the Store.
More precisely, the
SynchronizedStoreManager that's
going to perform synchronization
for us.
Now when we do this, we're going
to start off by creating the
OCKStore.
And then we're going to pass
that into the
SynchronizedStoreManager.
I want to pause here for a
second and highlight something
really important about CareKit
2.0.
Here, we're using the OCKStore,
which is our wrapper on top of
Core Data.
But the
OCKSynchronizedStoreManager can
interface with any object that
implements our OCKStore
protocol.
That means it would be possible
for you to wrap a web server, a
third-party database, or even a
simple JSON file, and use that
as your database.
For our purposes today, we're
going to stick with Core Data.
The next thing we need to do is
populate some data in the Store.
So we're just going to write a
handy extension to take care of
that for us.
In a real situation, you may
pull it down from a web server
or load it in from your app
bundle.
But today, we're just going to
code it up right in here.
Now we're going to create two
tasks, one to take a medication
and one to check -- or one to
log when you're feeling
nauseous.
So to do that, we're going to
need to create a schedule.
We're creating a couple of
dates.
Don't worry too much about
these.
The important part is down here
where we're creating the
schedule.
And we create that schedule by
composing elements.
We've got a breakfast element
that repeats every day.
So every day, we're going to
take our medication at
breakfast.
Another one every day at lunch.
And a third one every other day
at dinner.
You probably wouldn't actually
schedule medication like this.
But CareKit lets us make some
really flexible scheduling.
And we just wanted to show that
off a little bit.
With the schedule in hand, we
can now create our task.
To do that, we need to specify a
unique identifier.
We're going to use doxylamine.
This is a common medication
prescribed for nausea.
And we'll tack on the schedule,
of course.
And we'll provide some
instruction so that our
imaginary patient knows exactly
what to do.
Let's create one more task, this
one for nausea.
So in this case, we're going to
create a more simple schedule.
This schedule is going to run
every day, all day.
Because there is not any
particular time that you might
feel nauseous, we want you to be
able to log any time.
Finally, we'll create the task
for it very much the same way as
we did before.
The key difference here is that
we're saying that this task's
impact adherence property is
false.
You'll note at the top of most
CareKit apps, you'll see a bunch
of -- like a weekly calendar
with some completion rings in
it.
By setting this flag false,
we'll exclude this nausea task
from impacting those completion
rings.
Now that we have our two task
objects, we need to add them
into the Store.
Pretty straightforward.
And we've made it this far.
So we've got our medication
task, and we've got our nausea
task.
We also want to add in a couple
of contacts so that our patient
has somebody that they can
contact if they need help.
Contacts are created very much
the same way as other CareKit
entities.
You have to give them a unique
identifier.
And you can set a number of
properties on them.
In this case, we'll set an
image, a title, and a role.
And then we can also provide
contact information for them.
Here, we'll give them an email
address, a phone number, and a
message.
Finally, we're going to tack on
an address.
And this address will allow our
patient to get directions from
Maps if they need to get into
the office.
We'll add one more contact, very
much the same way as the first.
Finally, we're going to add both
contacts into the Store.
All right, so we've got our two
tasks in the Store.
We've got our two contacts in
the Store.
That brings us to the end of the
first step.
We've made it through creating a
Store.
And we've made it through adding
our data into the Store.
That means the second step is to
generate the UI.
We have to write the code to
tell CareKit how we would like
this displayed.
And the way that we're going to
do that is to write a
ViewController.
So here, we're creating our
careViewController.
We're going to go into this in
just a second.
But you'll note that I'm passing
in the storeManager.
This is going to be used for
synchronization.
Finally, we'll set this
ViewController as our root view,
so that when we run the app,
this is where we're going to
start.
Let's jump in here and see what
we have.
This is presently an empty
class.
You can see that inherits from
OCKDailyPageViewController.
If you're creating a CareKit
app, and you want some serious
customization power,
OCKDailyPageViewController is a
really good starting point.
When you inherit from this
class, what you're going to get
is a viewController that has the
calendar up at the top with the
completion rings in it.
And the user will be able to
page through that and select the
date that they like.
And down below that, you'll have
a second pageViewController.
And each time, the user changes
the date either by swiping or
tapping, you're going to get a
callback.
This callback, as a matter of
fact.
And inside of this function,
you're going to receive these
two parameters, a
listViewController and the date.
The date is the date that the
user has just selected.
And the listViewController is an
empty page of content.
And as the developer, your job
is to fill in the content that
you'd like the user to see for
the date they selected.
And doing that is very
straightforward.
Here, we're creating an
OCKChecklistTaskViewController.
And we can append that onto the
listViewController.
That will add it into the
content for the selected day.
So let's take a quick look at
this class, the
OCKChecklistTaskViewController.
Now you'll note from Srinath's
just -- talk just a moment ago
that there's CareKit UI and
CareKit.
And in CareKit UI, we had the
tasks views.
And there were four or five of
them.
Well, in CareKit, there's
parity.
And there's a matching view
controller for each of those.
The key difference is that the
views in CareKit UI are naive
and not synchronized, whereas
the view controllers in CareKit
will update automatically.
When we instantiate this, we
need to pass it the Store.
And we need to tell it which
task we'd like it to display the
data for.
Finally, we give it an event
query that specifies that it
should only show the events for
today.
So this is our medication card.
It's going to ask the patient to
take their doxylamine.
We'll add one more.
SimpleLogTaskViewController
takes the exact same arguments.
And this one is going to ask the
user to log when they're feeling
nauseous.
We've written a lot of code.
But we're finally ready to run
the app and see what it looks
like.
All right, so we're up and
running.
This is what we have so far.
You can see we've got both of
the tasks that we've added.
The user can swipe through the
dates on the calendar.
They can get back to today like
this.
You'll also note that on some
days, we have two events.
On other days, we have three
events.
That's due to the way that we
scheduled our task.
And when the user checks off a
task, the completion rings fill
up automatically.
This synchronization between the
tasks, the TaskViewController,
and the CalendarViewController
up at the top happens
automatically through the Store
synchronizer.
You'll also note that when we
log nausea events, they don't
show up in the completion ring
because we explicitly marked
those impacts adherence equals
false when we created our task.
Now before we move on, I want to
hit on two places where we can
really easily customize our
CareKit app.
And I think you guys will really
like these.
The first one, if we have --
hope back to our app delegate is
that we can set a tint color on
the window.
And this tint color will
propagate down through our
entire app.
And it's a really easy way to
apply styling or to brand your
app.
The second one is to switch out
the kind of task view that we're
using.
So you remember that there were
a number of different views for
tasks in CareKit UI.
And we can switch to a different
one simply by switching the
ViewController we're using.
They all have the same
initializers.
We'll rerun our app and take a
look at how this changes it.
Awesome.
So you can see the color is
different now.
And we also have an entirely
different task card to look at.
Now, what's really interesting
about this card is that it shows
the time that the user is
supposed to take their
medication.
But when we check one of these
off, the time that it displays
changes to the moment that the
user tapped the button.
This is really useful because it
allows our patient to see the
last time that she's taken her
medication.
All right.
I think we're ready to move on
to creating some charts now.
I think what we'll do is try to
put a chart right in between the
two cards that we have.
Maybe we'll make it a bar chart.
And we'll say that it will show
the number of times our patient
is taking their medication
versus the number of times that
she's felt nauseous.
So we'll drop down right here
between the two cards that we've
created already.
And we're going to need to
create two data series, one for
the medication, and one for the
nausea.
So we're going to start with the
nausea one.
When we create this data series,
we have to give it the
identifier.
This is a task whose data we'd
like to display.
We can give it a legend title, a
pair of colors to plot in, and a
marker size, which in this case
will dictate the width of the
bar chart.
And an event aggregator.
The event aggregator determines
the y-axis value.
And in this case, we're simply
going to count the number of
times that our patient has felt
nauseous.
We'll do this once more, this
time for our medication.
And it's going to be very much
the same.
With both of these in hand, we
can create an
OCKCartesianChartViewController.
The initializer takes the
storeManager.
Again, this is to provide that
synchronization that makes
CareKit so great.
And we also pass in a data
series, one for each series that
we'd like displayed on the
chart.
We also pass in the date that
we'd like the data displayed for
and the plot type.
Here, we're going to use the bar
chart.
But you could just as easily use
the scatter plot or the line
plot.
Finally, before we run our app
again, we're going to set a
couple of labels so that our
patient can understand the data
that we're displaying to her.
Let's run it one more time and
take a look at our chart.
Awesome.
So you can see down here we've
got our chart.
It's got data shown on it.
But what's really fantastic
about this chart is that it
updates in real time with
beautiful animations as we check
off data.
Perhaps on the first day, our
user didn't take her medication.
And she felt really sick.
On the second day, she started
to take it.
So she felt a little bit better.
And on the third day, she took
all of her medication.
And today, she also took all of
it and doesn't feel sick at all.
So you can see we're already
getting a pretty good patient
experience.
But there's another feature that
we can take advantage of that I
think you guys will really like.
CareKit now has the ability to
add arbitrary content anywhere
in this listViewController.
Let me show you how we can do
that.
So up at the very top, I think
we'd like to add a banner.
And we're going to do that by
creating this tipView.
We'll set some text on the
tipView.
And we'll also attach an image
to it.
But what's really important here
is that we simply append it as a
view.
Now what I want you to note is
that this tipView is not part of
CareKit.
We created it just for this
demo.
And it could just as easily be a
view that came from your
application or a third-party
library.
When we run our app now, you'll
see that we get this beautiful
banner up at the top that
encourages our patient to learn
more about the relationship
between exercise and healthy
pregnancy.
[Chuckles]
[ Cheering and Applause ]
You can imagine that there is a
plethora of ways that this could
be used.
You could populate this data
based on what's already in your
patient's Care Plan Store.
You could pull it down from a
server.
Or you could set it based on the
date.
The possibilities are really
endless here.
Now the last thing that I want
to do before we wrap up our demo
is give our user quick access to
her contacts.
And I think what we'll do is
just add a Care Team button up
here that shows a modal
presentation with all her
contacts in it.
And CareKit makes that really
easy.
Up at the top, we're going to
create our UI Bar Button item.
And we're going to set it to
call this function here, in
which we're going to create an
instance of the
OCKContactsListViewController.
This is a really handy class
that we provide for you.
All you need to do is pass it a
Store manager.
And it will automatically query
all the contacts in your Store
and display them for you.
Run our app one last time to see
what it looks like.
There we go.
So we'll tap on this and out
come our contacts.
Now, if our patient needs
directions into the office,
she's just a tap away from Maps.
It looks like it's about 4.9
miles.
That's not too shabby.
All right.
So we've got our contacts in
there.
And our app is looking pretty
good.
I think I'd like to wind down
the demo right here.
Let's call this complete.
But before we go back to
Srinath, I want to just reflect
for a moment on what we've done.
In what accounts for about 15
minutes and more or less 200
lines of code, we've been able
to complete a beautiful patient
care application with gorgeous
animations.
But what's most important about
this application is that it's
extremely modular.
None of the views know about
each other.
All of the viewControllers are
completely decoupled.
No delegates are set that tie
things together.
This app can be very easily
updated and changed as the needs
of our users evolve.
We think the possibility for
CareKit 2.0 is boundless.
And we are really excited to see
all the amazing things that our
developers are going to do with
it.
All right.
Back to you, Srinath.
[ Cheering and Applause ]
>> Wow, thank you, Erik, for
that great demo.
[Chuckles]
So now to just summarize the
whole session, CareKit is just a
fundamental rewrite and
rearchitecture of the framework.
It still holds on to its core
values.
But now it makes it extremely
powerful to use, to build like
really amazing Care app
experiences for your user.
So we spoke about ResearchKit,
where we talked about UI updates
that we've made throughout the
framework, as well as new
additions to our existing
library of active tasks.
And finally, we also touched
upon all the updates from our
community, including our two key
initiatives -- the investigator
support program, and our
redesigned website that's coming
this fall.
And as always, ResearchKit and
CareKit are Open Source
frameworks.
That's available right now on
GitHub.
Now over the next few months,
we're going to be working really
hard to add a lot more
capabilities to these
frameworks.
We'll be adding support for Dark
Mode.
We'll be adding accessibility,
localization, as well as more
documentation support as well.
And we would highly encourage
all the developers in our
community to provide us with
feedback as well as contribute
as we continue to evolve and
expand our amazing frameworks.
For more information about the
session, please visit this link.
We are also holding a
ResearchKit and CareKit lab
tomorrow at noon where all of us
will be there to answer any
questions that you have.
And with that, thank you all for
coming.
And have a great WWDC.
[ Cheering and Applause ]