Creating Independent Watch Apps

Session 208 WWDC 2019

watchOS 6 enables a whole new level of watchOS experiences by allowing fully independent apps and apps built just for Apple Watch, and by bringing the App Store to Apple Watch. Discover how to leverage the power of many iOS frameworks and technologies, now on watchOS, to create fully independent experiences on Apple Watch.

[ 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 ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US