My name is Keith Rauenbuehler, and I'm from the HomeKit Engineering team. Now, today we're here to talk about HomeKit with a focus on three specific areas.
First, we'll give an overview of HomeKit and the Home app. Then, we'll outline what it takes to build a HomeKit accessory.
And finally, we'll look at some HomeKit APIs and how to use them. So let's jump right in. So the best way to really understand the power of HomeKit is to take a look at the Home app. It's a single app interface to all of your HomeKit accessories.
Now, there are a ton of capabilities packed into the Home app, and we'll use this session today to talk about some of the most important ones. And the Home app currently exists on iPad, iPhone, and Apple Watch. And the Home app has three basic tabs. There's the Home tab, which is where you'll find your favorite HomeKit accessories and your scenes.
There's the Rooms tab, which is a great, it's a great tab to dig into a specific room and view all of the accessories associated with that room.
And the Automations tab, which is where you'll be able to set up and manage your smart home automations. Now, controlling accessory in the Home app is simple.
To toggle the state of it, just tap on the tile.
So if you want to turn on a light, all you need to do is tap on the tile for it.
Now, if you want finer-grain control, you can use 3D touch to bring up our quick controls. And so if we go back to that same light and we want to adjust the overall brightness -- say it's a dimmer switch -- we can 3D press on the tile, and we can bring up our quick controls.
Now, we've also added scenes to the Home app, and scenes are a great way to allow you control-- allow you to control multiple accessories with a single tap.
A scene is our simple interface for tying multiple accessories together, whether it's kicking off your morning routine or setting up your living room to the perfect movie-watching environment. Now, throughout the day, your home is always changing. People may come and go. Lights might turn on or off. Blinds can open and close. And scenes allow you to basically specify a desired state for all these accessories. So you can have a good night scene that turns off the lights, closes the blinds, locks the door, and sets the thermostat.
Then, when you're ready for bed, you simply tap on the tile for "Good Night," and HomeKit prepares your house for the evening.
Now, in iOS, we also have quick access to Home shortcuts via Control Center.
This is a great way to view and control your favorite HomeKit accessories, and it even provides access to your scenes. Now, this is very-- really convenient, but another great way to control HomeKit accessories is through Siri. You can tell Siri good morning, and that will kick off your good morning scene. You can also use Siri to control individual HomeKit accessories. So you can use Siri to turn on your light in the kitchen or to make sure your door is locked. You could even use Siri to bring up your favorite HomeKit camera stream.
Now, up until now, HomeKit has only existed on iOS, watchOS, and tvOS.
But this year, we're excited to announce that we're bringing the Home app to the Mac.
Now, we're really excited about this, as it's a great way to control your home using your computer, all without taking your phone out of your pocket.
It's also a great way to monitor your home because you'll get your HomeKit notifications right on your Mac.
And we've even built HomeKit Siri integration on the Mac as well, so you can use all of your favorite Siri triggers to control your accessories directly from your computer. Now, one of Apple's newest products, the HomePod, is my favorite way to control my HomeKit accessories. Not only is it a great music speaker, it's also a great way to control your HomeKit accessories because anyone in your house can use it using just their voice.
This hands-free Siri interface allows you to quickly and easily control these accessories in your home. It's really simple to get started, and I love using my HomePod to control the lights in my house.
It's especially convenient when I walk into the kitchen with my arms full of stuff, and I can use my voice to tell Siri to turn on the lights.
Now, we've also gotten a lot of feedback from users saying they love using their HomePod to trigger their good night scene.
They simply tell Siri good night as they head off to bed. Now, the HomePod also plays a much more powerful role in the home, as it helps control remote access and automations. Now, remote access is one of my favorite features in HomeKit, as it allows you to monitor your home when you're not there.
So you can have peace of mind, and you can check to make sure your garage door is closed or make sure your thermostat's turned off when you're not at home.
And you can do this all while being remote. Now, this feature requires a home hub, but HomePod, Apple TV, and iPad have the home hub functionality built right in. So with remote access, you can keep tabs on your home while you're away. And you may also want to share some of this support from this control with other users.
With HomeKit, you have control over granting remote access to some users and then specifying other users to only control accessories while locally. So let's talk a little bit about how remote access works.
So when you're in your home, your Apple device communicates directly with your accessories.
But when you leave your home, you'll need a home hub -- again, this is a HomePod, an Apple TV, or an iPad -- and your iPhone will communicate with your home hub, and your home hub will talk to your accessories directly. You can look at the latest state of these accessories. You can view the stream from one of your cameras. You can even lock your door if you've forgotten to secure your house before you left for the day. Now, we saw earlier how easy it to leverage scenes to get devices to work together. Now, scenes are great, but automations allow you to run scenes automatically. So you can do so without launching the Home app or using your voice. Automations allow you to control individual accessories or entire scenes based on some key triggers -- things like someone arriving home or having it run at a specific time of the day. You can even use other accessories in the house to trigger automations.
Automations can be as simple as turning on the back porch light when the back door opens or turning down the air conditioner when someone leaves.
Now, we also support more complex automations so you can open your garage door, turn on your lights, open your shades, and set your thermostat to just the right temperature all as you pull into your driveway. Now, this is one of my favorite automations, as I'm frequently juggling groceries, or kids, or even finishing up a phone call as I get home. This allows me to get in my house without needing to fumble with my keys as well.
Now, one of the key things that HomeKit provides to the customer is an incredibly easy way to add an accessory to your home and to your home network.
Other services often require downloading an app, following custom instructions, and jumping through a lot of hoops to get an accessory on your network. Now, if you've ever set up a non-HomeKit accessory, you know just how frustrating of an experience this can be. With HomeKit, the add accessory flow is really simple.
All you do is launch the Home app and scan the accessory code.
HomeKit handles the rest. It's really that easy. And accessories can also use NFC to make this setup even easier.
So you can launch the Home app, tap on the accessory with your phone, and you're done.
Now, the great thing about HomeKit is that it's both secure and private.
All accessory communication is encrypted, and we create a new shared secret for each session. The data is also private, so Apple doesn't have access to your camera streams. Apple can't listen in on your conversations. Apple can't even tell if you have a light bulb turned on or off.
We know your home is private, and we want to keep it that way. So you can monitor your home, control accessories, execute scenes, and even use full Siri support all in a secure and private way. We want this communication to be super secure, and so all messaging is done directly between the Apple device and the accessory. So your accessory never needs to talk to the cloud. In addition to this being secure, it's also really fast because all the messaging is done locally and there's no need to round trip to a server.
Now, our HomeKit Accessory Protocol is the communication channel for secure messaging between an accessory and your Apple device.
These messages are encrypted so that only the trusted devices can read them. This means that if someone else, something does intercept the message, they can't decrypt it and understand what it says.
And the HomeKit Accessory Protocol works over Wi-Fi and Bluetooth Low Energy. And by IP, we mean Wi-Fi and Ethernet. And Wi-Fi's great because it provides reliable, fast, long-range support, so you can position Wi-Fi accessories anywhere in your house. And we also support Bluetooth Low Energy. This is also great because -- especially for accessories that are battery operated. So for things like sensors, you can use Bluetooth Low Energy, and you can position these sensors in convenient locations because they don't require a power cord. Now, we want everyone to experience home automation, and so we provide lots of accessory categories, and we have some of the top manufacturers in each category. Now, we have an ever-growing list of categories, and we support multiple manufacturers in these categories. So you can find the one that's right for you.
With HomeKit, you can even combine accessories in the same category from different manufacturers and have them work together. HomeKit makes it easy for you to choose the accessory that's right for your home. Now, with AirPlay 2, we've added support for adding speakers to the Home app.
And in iOS 12, we're also releasing support for remote control systems.
Now you can create a remote control accessory that's able to control your Apple TV, including support for Siri. Now that we've given a quick recap of the benefits of using HomeKit, let's dive in and see what resources are available for making a HomeKit accessory. So the easiest way to get started with HomeKit and building an accessory is to become an MFI licensee.
It's a great program with lots of valuable tools that I can't wait to tell you all about. Now, if you just want to learn about the HomeKit Accessory Protocol, we also have that available for developers. Now, this is for noncommercial use to explore and experiment with the HomeKit Accessory Protocol.
So this is great for learning about the HomeKit Accessory Protocol, but if you're serious about building a HomeKit accessory, we really encourage you to join the MFI program because it's the best way to get off to a quick start. So let's talk a little bit about, what are the benefits of being part of the MFI program? So becoming an MFI is really easy, and you'll get lots of tools and resources. And one of the newest tools that we're really excited about is the HomeKit Accessory Development Kit. This is an easy way to get started on building a HomeKit accessory. Now, this Dis a set of code that runs on the accessory to help abstract away a lot of the implementation details that you previously have to worry about. Now, we also have tools to help with certification, and we also provide access to documentation to help you get off the ground. You'll also get a copy of the specification that has all the commercial support, including how to build authentication right into your accessory. Now, the ADK makes it easy than ever to build a HomeKit accessory.
Previously, you would need to worry about building your accessory logic, adopting the protocol, implementing crypto, adopting WAC, all these other steps. With the accessory development kit, we've abstracted all this away for you. So we provide the platform logic for your specific accessory, and the HomeKit Accessory Development Kit handles a lot of the details. This means you only need to worry about that accessory logic, which is the part that's unique to your accessory and is the part of the code that you care about.
Now, the HomeKit ADK is new, but we've already gotten a ton of great feedback from our partners on how simple it is to use. MFI licensees are finding it easier than ever to get started, and we're seeing that the ramp-up time for new partners is faster than ever before.
And of course, the ADK is reliable and secure, as we've tested it thoroughly internally, and it's been reviewed by our security folks. Now, the really nice thing about the ADK is that we'll continue to update it throughout the year, so whenever there's an iOS update that releases new support for accessories or to the spec, we'll also rev the ADK so that it'll stay in sync. So how much faster is it to use the ADK? Well, with the ADK, you can build a functional prototype and have it up and running within just a week.
But let's look at how that impacts the overall timeline. So previously, our partners were spending about 6 months for development, and then they'd have to do integration, certification before they could ship their product. We were finding this would often take about a year to complete.
So with the ADK, we're seeing that timeline get dramatically decreased.
Based on feedback from our partners, it's now possible to ship out HomeKit accessory within just 3 months.
The ADK makes it easier than ever to build a HomeKit accessory. To learn more about it, join the MFI program. You'll have access to all the ADK information that our licensees are already using today to build great accessories.
Now, I mentioned authentication before, so let's talk a little bit about that. So this is an important part of the MFI program. Now, our customers trust when they see that Apple logo. They trust that they're buying a high-quality product. So when they buy an accessory that works with Apple HomeKit, they trust that their accessory has been tested thoroughly and reviewed by Apple. Now, this process is similar to the App Store review process, so on the HomeKit side, we have a way of reviewing accessories.
This is so they, we ensure that they meet our high bar of quality and that they're ready to be shipped to customers. Now, once an accessory is certified, it uses our authentication stack for onboarding. This helps guarantee that a customer is getting that high-quality product. Now, the authentication itself can be done using our hardware chip or via our new software-based authentication. Now, as an MFI licensee, you'll also have access to manufacturing partners that can help get your product to market. So if you're sitting in the crowd today with a great idea for a HomeKit accessory, this is your big opportunity to bring it to the home. Now, we've always supported hardware-based authentication, but we have also recently began supporting software-based authentication. Now, customers can be guaranteed the same level of quality and trust, and the integration support can be rolled out via a firmware update. Now, this is great because this means you can roll out HomeKit to accessories that are already shipping to customers. Now, there are three other great tools that I want to talk about this morning.
The first is a resource for accessory developers, and this is available for MFI licensees, and this is the HomeKit Accessory Tester. Now, this is an app that allows an easy interface for helping you test your accessory.
This is a great way to validate that your accessory is ready to be submitted to the review process. Now, the second tool I want to talk about is the HomeKit Certification Assistant.
Now, this resource is also available to MFI licensees, which is another great benefit of being part of the program. And this is built on top of that HomeKit Accessory Tester. Now, this allows you to self-certify your accessory and even has support for automating some of that testing process. And the third tool I want to talk about is the HomeKit Accessory Simulator.
Now, this is a tool that's created for app developers, and so it will simulate various accessories. Now, this allows you to test your app and make sure it plays with all the HomeKit accessory categories. Now, the really nice thing about this is it means you don't need to go out and buy each one of these accessories to do your testing. You can get this tool available through Xcode and also through the MFI program. And this is actually one of the tools that we use internally, as it's a great way to quickly and easily set up a complex home with lots of accessories.
Now, of course, you'll also want a test with real-world accessories as well. Now, we talked quite a bit about making a HomeKit accessory, but what about making a HomeKit app? So let's switch gears and talk about what it takes to build a HomeKit application. So there are lots of apps out there on the App Store.
How do you make yours stand out? Well, for HomeKit, it's important to think about your target audience. So that might mean extending custom functionality, like tuning or calibrating an accessory, or maybe it means you live in a region where there's some functionality that's specific to your locale that doesn't already exist in the App Store. And if you're an MFI licensee writing an app for your accessory, you may what to be able to support custom services and characteristics. Now, with HomeKit, there's a lot of APIs that I'm going to talk about today, but before I get into the details, I think it's important to take a look at a high level at the object hierarchy. So the first class that I want to tell you about is this core object, which is the HMHome. Now, this is corresponds to the overall home, and within the HMHome, you can also optionally have HMZones. Now, these are things like upstairs and downstairs.
Now, you could also have HMRooms, and these are the rooms that are normally associated with the home -- the kitchen, the living room, the dining room, the bedroom. And within those rooms, you can have HMAccessories. And these are the lights, the fans, the cameras, the locks, all the normal accessories we support.
So your home, the HMHome contains HMZones. The HMZone contains HMRooms. And the HMRoom contains HMAccessories.
Now, the home has a handful of properties on it, but the home is really used as the central organizing object for HomeKit. So the home is how you add accessories, configure rooms, create scenes, and build automations.
But some users may have more than one home, and so you'll need to use the HMHomeManager to help manage these homes. So if you want to add a new home or remove an existing home, that's done through the HMHomeManager APIs.
Now, the great thing about HomeKit is you can extend home control to other users. We also have access control capabilities so you can give a spouse or a roommate full administrative privileges. Now, as an administrator, they, these users can add accessories, edit scenes. They basically have full control over the home.
But you may only want to give some users normal access to the home and only allow them to control accessories and not edit them. And those are non-administrators.
Now, the important take-away here is that if you're building an app, you want to make sure that if your HM user is not an administrator that you disable some key functionality so that it doesn't fail when they go try and use it. Again, all this user management is done through the HMHome object, and you'll quickly see that this is a common design pattern we use where the HMHome exposes a lot of the basic functionality. So let's take a look at some sample code and see what this looks like. So here we have a class where we will instantiate an HMHomeManager. Now, we want to add a home to that home manager, so we'll use the addHome APIs and specify the name of the home. Now, we want to be sure to set ourselves as the delegate, so we'll get the appropriate delegate callbacks. And finally, if we want to configure the users for the home, we'll call manageUsers on HMHome.
Now, I mentioned HMZones earlier, so let's take a little peek at that. So this is a way of grouping multiple rooms together, like upstairs and downstairs, or you can group all the bedrooms together in a single zone. So it has some basic properties on it like name and access to the rooms, but it also has this unique identifier property. And this could often be overlooked, but this is a way that you keep track of which zone you're, you care about. So when the name changes or the rooms change, you still have an access to that specific zone. Now, on the HMRoom object, we also support exposing the name and the list of the accessories, and it also contains this unique identifier property so you can keep track of rooms as well.
Again, the rooms and zones are managed through the HMHome APIs, so if you want to add or remove a room or if you want to add or remove a zone, you do through, do that through the HMHome APIs. So if we go back to some sample code, let's take a look at this in action. So here we are adding a room to the home with our roomName. And then, we're adding a zone to the home with a zoneName. And then, we associate that room to the zone.
Now, the next level of object hierarchy that's important is the relationship between accessories, services, and characteristics. Now, this can sound confusing, as accessories contain services and services contain characteristics. So it's best to look at a real-world example to give you an idea how, really how this fits together. So let's say you have a ceiling fan fixture.
Now, this is a single accessory, and it has a light, and it has a fan. So this maps to a light service and a fan service.
Now, these services have a set of common characteristics that are shared across all services, but they also have characteristics that are unique to their service.
So the light service has characteristics like power, brightness, and saturation. And the fan service has characteristics like power, rotation speed, and rotation direction. Now, some of these characteristics are optional. As you can imagine, not all lights support saturation and color. But the HomeKit APIs expose these as a way to elevate these services to your user.
So we look back. We have the ceiling fan fixture, which is the HMAccessory. We have the light service and the fan service, which are the HMServices.
And we have the corresponding characteristics, which are the HMCharacteristics. So we look, if you look at the API for some of this, you could see we have HMAccessory, and this allows you to learn about the accessory that you're controlling. So this exposes properties like the name, the list of services it supports, and the firmware version it's running. Now, this is just a subsample of all the properties on the accessory. I just wanted to give you an idea of the sense of what types of properties are on it.
So if we take a look at HMService, we'll see that it exposes the list of characteristics, and there's a setter method for updating the name. Now, updating the name is actually pretty important.
So why is it important? Well, it's important because this is how Siri and the Home app will interface with your accessory.
So you'll want to choose a good default name. So we, you don't want to use serial numbers, or MAC addresses, or model numbers in your service name because that'll make it challenging for the user to talk to your accessory through Siri. You also don't-- want to avoid special characters and numbers, emojis, punctuation, things like that also because it gets confusing to the user on how they want, when they want to address their accessory. Now, we support over 40 predefined service types. So things like light bulbs, thermostats, garage door openers, outlets, and all kinds of sensors, to name a few. We also allow the ability to specify custom service types as well. Now, when it comes to adding the accessory to the home, you'll want to go back to the HMHome helper methods. These APIs are pretty simple to use, but we'll walk through an example shortly here anyway. So the addAccessory API, this API is what invokes the Home UI view service, which is that familiar addAccessory flow that I mentioned earlier, which is how you can do quick QR code scanning or use NFC to add an accessory to the home.
Now, I want to call special attention to the last method here, which is addAnd SetupAccessories with payload. Now, you can use that payload to pass in a HomeKit accessory code for in-field activation cases. So this API is especially valuable for software authentication. So this is the case where your accessory has left the factory without a HomeKit code on it. So you've updated the accessory via firmware update to provide HomeKit support, and you don't want the user to have to memorize the HomeKit code or to write it down. And so this API allows you to pass in that HomeKit code so that this accessory can be seamlessly added to the home. Now, this API is available to MFI licensees. For more information, contact your MFI representative.
So if we look at some sample code on how we would add an accessory to the home, you just need to call addAnd SetupAccessories on the home object, and HomeKit takes care of the rest. Now, I mentioned scenes earlier, but it's a pretty powerful concept, so I want to go a bit deeper.
Now, this is how you can integrate different types of accessories together to help provide a cohesive experience. We have some suggested scenes, but we also allow full customization by the user.
Now, one of the great things about scenes is that Siri understands what scenes are. And so speaking the name to Siri execute, speaking the name of a scene to Siri will execute the scene directly. Now, we don't call them scenes in HomeKit. We call them HMActionSets.
So if you want to create an HMActionSet -- for example, arriving home -- you'll need to create a list of HMActions, and then you'll associate those with the action set. So the action set, the HMActionSet contains all of the individual HMActions.
Now, we support some predefined scenes, like wake up, go to sleep, leave the house, and return home. Now, this not only gives the user some context about what types of action sets are possible, but this is also what we've found to be some of the most useful. Now, of course, we also support user-defined action sets, and these are great for things like creating your perfect movie scene lighting.
So again, to add them to the home, we go back to the HMHome APIs because this allows you to add these action sets, execute the action sets, and the HMHome APIs also expose the way of accessing the built-in action sets. So if we look at some quick sample code, we'll see that if we want to create an action set, we call addActionSet withName on the home, we pass in the name of the action set, then we'll want to iterate through our list of actions and add each one to the action set.
Then, later, if we want to run the scene, all you do is call executeActionSet on the home.
Now, running scenes via the UI or via Siri is great, but sometimes you want things to happen automatically. Now, we have several options for automatically triggering scenes and automatically controlling accessories. These can be geofence based, so you can turn on the lights as you pull up to your house. Or they can be time based, so you can turn up the heat before you get out of bed. They can be accessory based, so you can leverage a motion sensor to turn on a light. And they can be presence based, so you could turn off your lights when you leave for the day.
Now, event triggers themselves are comprised of action sets, and the APIs on HMEvent or HMTrigger are mostly around naming, adding, and enabling. Now, with automations, you can set them up to run once ever, or you can have them be recurring.
So you can them just be, happen that one time, or you can have them happen every day, or maybe you want them just to happen every weekday, or even just every Friday.
So with automations, you have a lot of control with the frequency and how often you want automations to run.
Now, let's take a look at the creation of an HMTrigger and how we add it to the home.
So let's say we want to create an automation that will run every night at 7 p.m. So first, we create our date components and we set the time to be 7 p.m.
Then, we'll create a calendar event using that component.
Then, we'll generate a trigger using that time event. Now, we need to add that trigger to the home. And we need to add the action set to the trigger. So this allows you to run an automation every night at 7 p.m. So let's say it's turning on a light every night at 7 p.m. Now, that's great, except for sometimes, some parts of the year, it's not dark at 7 p.m., or sometimes, parts of the year, it gets dark before 7 p.m. Sometimes it gets dark after 7 p.m. So turning on the light at 7 p.m. every night isn't really what you want. So we also support what we call significant time events. And this is sunrise and sunset. So if we look at that previous example, we could change that to say, turn on the light every night at 7 p.m. We also support relative time offsets, so you can have the light turn on, say, 30 minutes prior to sunset. So let's go back to the code we had before and make some changes so that we can have it run every night at 30 minutes before sunset. So the first thing we need to do is change our date components to be 30 minutes. Now, you'll see that it's negative 30 here because we want it to run 30 minutes prior to sunset.
Then, we'll create a significant time event for sunset and pass in that offset. Then, when we generate our trigger, we pass in the sunset event.
Then, we execute the code we had before, which is adding the trigger to the home and adding the action set to the trigger.
But sometimes you don't want these automations to run.
You probably don't want the heat to turn on in the morning if no one's home. You probably don't want the light to turn on when the door opens if it's during the day. So we also support what we call conditions.
And these can be time based, they can be presence based, they can be accessory state based, and they can be based on significant events. Now, I have an automation in my house which turns off the lights whenever someone leaves. Now, that's great, except that I live with my wife, and so whenever she leaves the house, all the lights turn off and I'm left in the dark. So with presence-based conditions, you can update this so that the lights only turn off when the last person leaves. Now, to set these conditions, we use predicates. So let's take a look at some sample code.
So here we can see that we're using our same sunset time offset from before. Now, we're going to create a presence event that's when users are at home. We're going to use that presence event to generate a predicate.
And we'll pass that predicate into our trigger generation. Then, we'll go back to the same code we had before where we add the trigger to the home and we add the action set to the trigger. So now, we've gone from having an automation that runs every night at 7 p.m. to an automation that runs every night 30 minutes before sunset, only if someone's home.
Now, we also have support for HomeKit cameras. And there are some HomeKit APIs that allow you to show live streams, show still images, and to configure camera settings.
You-- this support also includes the ability to control the speaker volume and microphone. So let's take a quick look at some sample code for that as well.
So here you could see we have a function where we want to start the camera stream for our accessory. Now, we want to be sure to set ourselves as the delegate so we can get the proper delegate callbacks.
Now, we'll use this start stream API to start the stream, and we also want to be sure to create a camera view and to add that view to our view hierarchy. This is so we can display that camera stream in our app.
Then, later, we'll get the delegate callback. Again, this is the HMCameraStream ControlDelegate.
And we'll receive this cameraStreamControl DidStartStream delegate callback.
And all we need to do there is set the camera source to be the camera stream. Now, this is the end of the sample code for today, but there's plenty of documentation available for these APIs online. So we hope that this gives you a fresh look at learning what, how HomeKit works. We encourage you to join the MFI program to take advantage of all these great resources and powerful tools.
It's amazingly easy to become an MFI licensee. Come visit us in the lab to learn more about it. If you're already an MFI licensee, contact your MFI representative to get access to the latest tools.
With the new ADK, we've made it easier than ever to bring a HomeKit accessory to market.
Whether you're building HomeKit through, your accessory through a firmware update or creating a new HomeKit accessory for the first time, use these tools to start integrating with HomeKit so you can get native series support and to integrate with other HomeKit accessories. We can't wait to see the great accessories we know that you'll come up with. We also encourage you to use these APIs to provide a unique experience for your customers and to take full advantage of all that HomeKit has to offer. For more information or to learn about anything we've discussed today, check out this link or come visit us in the lab. We're going to be down in the Technology Lab 12, which starts shortly. Thank you all for coming. Hope you all had a great WWDC. [ Applause ]
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.