Transcript
[ Applause ]
>> Hi everyone.
My name is Neil Desai
and I'm a watchOS
frameworks engineer and I am
really excited to talk to you
all about how to create some
great independent watch apps.
We're increasingly seeing people
enjoy being able to go out with
just their Apple Watch.
Users love the quick
interactions and the freedom
Apple Watch gives them.
Whether it's going out with just
their watch while working out,
running an errand, or quickly
answering a call, Apple Watch
helps keep you connected to the
people, information, and apps
you care about most.
And in these moments where the
user is enjoying the freedom of
Apple Watch, users think of
their iPhone as optional.
And we want our watch apps to
match our user's expectations of
Apple Watch.
And to do so we're introducing a
new concept, a concept we call
independent watch apps.
So now your iPhone app can be an
optional experience.
And a lot of apps already are
independent to some degree.
Outcast is a great example of a
podcast app where I can control
the entire experience directly
from my wrist.
And CARROT Weather is another
great example of an app that I
always check the weather on and
I only do it on my Apple Watch.
And whenever I'm traveling
abroad I always use Elk for
currency conversions.
However, these apps all have an
iPhone app.
And now we're saying that the
iPhone app is optional.
And for the first time, you can
ship a watch only app without
having to ship an iOS app at
all.
[applause] Thank you.
[ Applause ]
And to help your apps become
independent we're introducing a
bunch of new features this year
for watch apps, like being able
to send push notifications
directly to the device, and
helping to make sign on even
easier and a whole bunch of
other features.
But first I want to talk about
how we actually install these
applications.
Now up through the Watch iOS 5,
the Watch App has been embedded
within the iOS app and we
download both of them to the
iPhone, and then the iPhone
handles the task of installing
the Watch App from iPhone to
Apple Watch.
And we're just going to
completely change this in iOS 13
and watchOS 6.
So now the App Store server is
going to install whatever it
needs to install wherever it
needs to install it.
And it's going to apply to all
applications in the store today.
And so this means that the iOS
app no longer includes that
Watch App and some of you may be
happy to hear this, the Watch
App is no longer going to count
against your iOS app cellular
download limit.
And-- [applause] Thank you.
[ Applause ]
And we're able to do this by
bitcode recompiling all the apps
on our App Store servers and
separating out the iOS app from
the Watch App.
And this means that each device
is going to download its own
app.
So the iPhone gets an iPhone
app.
The watch gets a Watch App.
And because of this, because
we're able to install directly
to the device, we're now
enabling asset and variant
thinning for watch apps for the
first time.
So if your user has a Series 4
device, and, then we can install
the appropriate variant and
architecture size specific to
that device and not any other.
And we can apply that same logic
to assets.
So if you've configured your
asset catalog to have a
particular asset to a particular
device, then we can install just
that asset to that device.
And really this is just a fancy
way of saying downloads are much
smaller and Watch App binary
sizes are much smaller.
And if you're using Swift,
because of Swift 5 and ABI
stability, now the Swift dylibs
aren't included within your app
at all and so the downloads are
going to be even more smaller.
And so that's how we install our
applications.
And let's talk about how our
users are going to get them.
So your apps are still
discoverable in the iOS App
Store, but now new in watchOS 6
we're introducing the App Store
for Apple Watch.
And it is a fully featured App
Store complete with feature
sections, full product detail
pages, search, editorial.
And I got to say, you can even
purchase an app from your wrist
and when it happens it is so
cool.
I seriously love it.
And, so now let's talk about the
different types of apps and how
they function with this, in this
new Watch App Store.
So all the apps that exist in
the store today are what we call
dependent apps because the Watch
App is considered dependent on
the iPhone app by the system.
And so if I get one of these
dependent apps from the Watch
App Store on my watch, then the
system will kick off a download
of the iPhone app to iPhone.
And until that happens that the
iPhone app is installed, the
watchOS app launch is going to
be blocked because the system
considers that Watch App to be
dependent on the iPhone app.
And now unlike dependent apps,
independent apps are where the
Watch App can fly solo which
means the phone app doesn't need
to be installed to launch the
Watch App.
So that means the Watch App is
installed independently.
And if your user has both an
iPhone and Watch App installed
at the same time, now your user
can actually uninstall the
iPhone app and the Watch App
will remain.
And for those of you that are a
little nervous about, and your
brain's already thinking how
does this affect my app that
exists in the store, you'll be
happy to hear that independent
watchOS apps with an iOS app are
completely backwards compatible
with older OS's.
And those new watch only
applications-- [applause] Thank
you.
[ Applause ]
Thank you.
Those new watch only
applications are supported on
watchOS 6 or later.
And if you need to distribute
your app within an enterprise
for instance, you'll be happy to
hear we have full Xcode support
to also create those different
variants we were talking about
to split out your iPhone and
Watch App.
And new when you go through the
flow with Xcode, in the manifest
plist that gets generated,
there's a new platform
identifier key that's added to
tell the system what to install
and where to install it.
So now that we know the
importance of independent Watch
App, let's talk about how to
make your watch apps
independent.
And so let's, by doing so let's
jump into Xcode and now I'm
going to show you how easy it is
to take your existing app and
make it independent.
Cool. So here we are in Xcode
and I have a great Watch App
here that's currently a
dependent app.
And this is-- I've already done
all the work to make this app
independent, and because it's a
great flashcard app that exists
on Watch.
So we can build and run this
application and see that the
phone simulator and the watch
simulator are exactly like we
expect in our normal debugging
flow.
And so now the Watch App gets
launched and I can immediately
start a debugging session.
But now let's tell the system to
make this app independent.
So let's stop that debug session
and now in the target editor for
our WatchKit extension I see
under deployment target there's
a new checkbox called supports
running without iOS app
installation.
So I'm going to check that off,
and then I'm just going to build
and run.
And by doing so, by checking off
that box, I now told the system
it's independent.
And I was kind of fast so let me
actually show you one cool
thing.
So let's actually close out the
iPhone simulator because this
app's independent.
Why do we need that iPhone SIM
anymore?
Let's just build and run once
more and now I build and run
only to the watch simulator and
it provides a much faster
debugging experience.
[ Applause ]
Cool. Great.
So now let's start and build a
watch only application for the
first time.
So I'm going to close out of
this project, and to create a
new application I'm just going
to go to file, new project, and
then under watchOS I see there's
a Watch App and then there's
also an iOS app with a Watch
App.
And I of course only want to
build a watch only app right
now.
So let's select that.
Great.
And then of course let's use
SwiftUI.
It's pretty cool.
I hear a lot of good things.
[laughter] And then let's also
include a complication.
And then let's save that off to
my desktop.
Perfect. Let's just [inaudible]
and now let's just build and
run.
And again, just like the
independent app we were just
talking about, we don't need the
iPhone simulator, we're just
building and running a simple
watch only application directly
to the watch simulator.
Great.
[Applause] Thank you.
So we were able to talk about
how to migrate your existing app
and make it an independent watch
app.
We were also able to build a
watch only application and we
talked about how the simulator
experience is much improved.
And along the same vein as that
simulator experience, let's talk
about debugging.
So debugging on watchOS 6 is--
for simulator is up to 10 times
faster now.
[applause] Thank you.
And device debugging is up to
twice as fast and we've done a
lot of work this year to make
sure it's more reliable than
ever before.
And the debugging experience is
proxied through iPhone but I
wanted to call out one little
pro tip.
So if your devices are on Wifi--
your phone and watch-- then a
faster route will be chosen by
the system and you'll see a much
faster debugging experience.
So let's dive into the different
aspects now of how to make an
app independent.
So to do so we're going to talk
about three major things.
We're going to talk about how do
we get our user data, via
authentication or any private
user data, directly from our
user.
We're going to talk about how to
push information to the device.
And lastly, we're going to talk
about dealing with connectivity
and gathering our own
application data.
So let's first talk about
authentication.
So the primary way to deal with
authentication is via sign in
and sign up.
And now on watchOS 6 you can
build sign up auth directly on
the watch.
And you can support terms and
conditions using the WK alert
action API.
And new on watchOS 6 as well as
all of our other Apple
platforms, will now support Sign
in With Apple.
And we're going to talk a little
bit about how you can build your
own custom password based sign
in.
So let's first talk about Sign
in With Apple.
Sign in With Apple is a simple,
secure, and private way to get
authentication from your user.
And your user doesn't have to
fill out any forms.
There's no new password they
have to think of.
And they can just simply select
an email address and it just
continues signing in.
And each account has two factor
auth built in and there's no
email verification that a user
has to do.
And we support sign in across
all devices.
And there's also a JavaScript
SDK for any other type of
device.
So to use Sign in With Apple,
make sure and use the
authentication services
framework which is now available
on watchOS.
And if you have any specific UI
you want to build, you can now
use an authorization Apple ID
button and embed that within
your application.
And then once the user actually
taps on that button you'll
receive your ID action and then
you can use the authentication
services framework to display
the appropriate system UI.
And there's a lot of great talks
this week.
If you want to know some more
about Sign in With Apple, I
highly recommend them.
Great. And to enable Sign in
With Apple in your Xcode project
on your WatchKit extension, just
add a new capability and enable
your Sign in With Apple
entitlement.
And that's how to easily get
started.
And now you may have your own
custom password based sign in
and we're introducing a text
field new to watchOS this year.
And so you can embed this text
field from within SwiftUI or
WatchKit.
And so you can build a UI such
as this where we're just asking
our user, hey we just need a
username and password and we're
using the placeholder text to
instruct our user what to
particularly input.
And if you set the appropriate
text content type for that
particular text field, then the
system text input controller
that gets brought up will change
itself for the appropriate text
type.
And so for this flow, say the
user taps on username and then
the system text input controller
gets brought up.
The user can then elect to enter
text via dictation or scribble,
and there's now a new option
called continuity keyboard.
So if a user taps on this, then
the Apple Watch will say, hey
finish entering some text on
your iOS or iPad OS device and
you can see they'll receive a
notification on your iPhone or
iPad if they have the same
iCloud account logged into it.
And if you've ever used tvOS
with text fields, this flow will
look very familiar.
And once the user taps on it,
they can easily enter in text
into their iOS keyboard.
And again, the text content type
like we talked about earlier is
going to inform the auto fill
suggestions here.
And then the user can elect to
select an auto fill suggestion
from either their iCloud
keychain or the user's preferred
password manager.
And now to get your-- you want
to make sure to get your
password auto fill suggestions
elevated by the system.
And so to do that, make sure to
set the correct text content
type and add associated domains
to your WatchKit extension.
Now associated domains are a
great way to tie your app and
website together and in this way
it lets the system know that hey
the credential that might exist
in the user's iCloud keychain
can get elevated and displayed
at the top of the iOS keyboard.
And once the user selects on an
auto fill suggestion, then the
system will make its best effort
to auto fill both the username
and password at the same time.
And for password based sign in,
sometimes you may need to
support one time codes.
And so if you set the correct
text content type, then a
one-time code can get auto
filled if you sent it via maybe
an iMessage or a text message,
and then the system text input
controller will show that auto
fill suggestion.
The user can easily select it
and then go about and continue
with authentication.
[ Applause ]
So again, [inaudible] text
field, you can use that from
within SwiftUI or WatchKit.
Make sure to set up your
associated domains to elevate
the appropriate auto fill
suggestion and test out your
flows with continuity keyboard
and build one time code support
if you need it.
Now, another type of user
information we sometimes need is
private user information and we
want to ask our users for that
information via the different
frameworks available.
Now on watchOS, we've already
supported giving access for
calendar, contacts, motion, and
even other types such as
location directly on Apple
Watch.
And now with watchOS 6, we now
support giving health
authorization directly on Apple
Watch.
[applause] Thank you.
So the user can elect to give
access to all of the data
requested or even just
particular types.
So that's how we deal with
getting user data in an
independent app world.
Let's now talk about how to push
information to a device.
And of course the best way to
push information to a device is
via push notifications.
And now with watchOS 6 the watch
has become a standalone push
target for the first time.
[applause]
And so this means you can send
user visible notifications and
background notifications
directly to Apple Watch.
And this is based around the
user notifications framework and
we're using the exact same
infrastructure as all other
Apple devices.
So from an overview perspective,
your server will send an APNS
request header and payload
directly to APNS and APNS is our
Apple Push Notification Service.
And then APNS is going to send
that payload down to the
appropriate device.
On watchOS, the payloads are the
same as on all other platforms
we have.
And on the APNS request header,
there's one new key and that new
key is an APNS push type.
And this is supported on all of
our Apple platforms and on all
OS's.
And so you can set that key to
be either alert or background.
And the way I like to think
about this is if the user's ever
going to see a notification,
they're going to get alerted to
something, then set alert in the
push type.
And if you need to send a
background notification to just
wake up your app in the
background on the user's device
whenever there's new content
available, you can use the
background push type.
And so for registration and
delivery for-- for registration
we're going to get our tokens
for WatchKit.
And then just like forwarded
notifications in past releases,
your alert notifications will
get delivered to your watch apps
in the same manner as before
using user notifications in
conjunction with WatchKit.
And your background
notifications will now get
delivered on your WK extension
delegate.
And if you encrypt any of your
payloads, we now have full
notification service extension
support on watchOS as well.
And so you can just decrypt that
payload directly on the device,
and then show it to your user.
And in your Xcode project, to
enable push notifications in the
target editor, if you select
your WatchKit extension you can
then just add a new capability
and enable the push
notifications entitlement.
And if you want to support
background notifications, you
can enable background modes and
then just enable the remote
notification checkbox.
So let's dive into some code
now.
So here we are in our extension
delegate and the application did
finish launching.
And the first thing we want to
do when we register for
notifications is first ask our
user if that's okay.
So we're going to request
authorization on our UN user
notification center.
And if the user elects to grant
us access, then we can just call
register for remote
notifications on our WK shared
extension.
And after using so, if we
implement our did register for
remote notifications call, then
we can get our device token and
forward that notification over
to our notification provider for
our own server.
And of course we want to make
sure an implement did fail to
register to remote notifications
just in case something failed.
And then for background
notifications, those will get
delivered on did receive remote
notification with a fetch
completion handler and a
background fetch result.
So once you receive this you can
handle your background
notification and then just call
the completion handler with
whatever the appropriate
background fetch result is.
So again, that APNS push type,
that new key on the APNS request
header, is required when sending
pushes to watchOS.
And it's supported on all
platforms.
So really if you're sending any
notifications to any Apple
devices, just make sure to add
the APNS push type.
And your APNS topic key on your
APNS request header is going to
be your WatchKit apps bundle
identifier not your WatchKit
extension.
I just want to quickly mention
that.
And if you have multiple apps
like an iPhone app and a Watch
App, you want to send your
notifications to both devices
simultaneously.
And when you do so, the system
will appropriately de-duplicate
the notifications when they're
sent simultaneously.
And another great way to push
information to a device is via
complication pushes.
So complication pushes are a
great way to update your app if
your complication is enabled on
the active watch face.
And this is done via PushKit
which has not been made
available on watchOS.
And you can use PushKit for both
your registration and delivery.
So if you're using the old
complication push mechanism
that's based on iOS, we
recommend you just send your
complication pushes directly to
the watch now.
So in code, we can just register
for complication pushes by
setting up our PK push registry,
set up our delegate, and then
specify some desired push types.
And then once we do so we're
going to get our device token
and we just forward that off to
our server and handle any
invalidations that might occur.
And then when we actually send a
push and deliver one, then we
just implement the appropriate
PushKit method and just handle
receiving that complication push
and then reload our complication
timeline.
So great.
That's how we push information
to a device.
Now let's talk about how to
gather application data and deal
with connectivity.
So in general in terms of
networking, we want to use
URLSession which has been
available for quite some time on
watchOS.
And for those that use CloudKit,
we can also use CloudKit to
gather application data.
So if you're using watch
connectivity and depending on
your iPhone app for any
particular data, you're going to
want to migrate all of your
watch connectivity usage over to
NSURLSession.
And again, the watch, a lot of
times users will only use their
Watch App for a couple seconds
and then immediately put their
wrist down, so make sure to use
background sessions to ensure
that your URLSessions will
appropriately complete.
And so watch connectivity is
still available and you can
still use for any companion
app's specific interactions.
But really only use it if you
really need to.
And there's a Boolean property
is companion app installed to
let you know whether or not the
iPhone app is there.
So in CloudKit, if you're
already using it you'll be happy
to hear we have full CK
subscription support now on
watchOS and, which goes hand in
hand with supporting CloudKit
notifications.
So if you don't want to manage
your own server or notification
provider, you can just use
CloudKit to send notifications.
And there's a great talk
available online if you want to
check out some more information
about CloudKit and its best
practices.
And so for CK subscriptions,
they're a great way to subscribe
to database changes that are
occurring on any other devices.
And then you'll get a background
push notification that'll tell
you when to update your
application and then you can
retrieve only what has changed
between your app and your
CloudKit container.
And from a high level look at
it, say your user is using an
iPhone app and they made a
database change.
That database change will get
sent to the CloudKit and then
CloudKit's going to realize, oh
hey, there's a subscription, and
then CloudKit will then tell
APNS to send a background
notification down to any other
device that has a subscription,
in this case, our Watch App.
And then if the Watch App, if
the user makes a change with the
Watch App, then the cycle will
just repeat itself.
And how we send notifications is
governed by the exact same rules
as on all of our other devices.
To set up your CloudKit
subscriptions, you can set up
your notification info and then
make sure and set your should
send content available to be
true.
And then CloudKit's going to
deliver your push on that same
delegate callback we were
talking about earlier, your did
receive remote notification.
So then you can just handle that
and retrieve only what has
changed between your app and the
CloudKit container.
So great. Those are the three
major ways we think about how to
make watch apps independent.
How do we get user data and then
also how do we push information
down to the device?
And lastly, how do we actually
deal with getting our own
application data?
So users love the freedom and
independence that Apple Watch
gives them and now there are a
bunch of system and developer
capabilities at your disposal.
So make sure to make your watch
apps independent because,
honestly, customers probably
already expect their watch apps
to be independent, and now more
than ever.
So there's some great
information available online
with some sessions and labs.
And thank you all everyone for
coming and I hope you all have a
great WWDC.
Thank you.
[ Applause ]