I know what you’re thinking. That was a lot of setup for a little “Hello, World!” app. Why so complicated? The reason lies in that WatchKit extension you created. It’s a lot like other extensions on iOS—sharing, activity, photo editing, and the like—in that it’s basically a tiny app that lives inside your main iPhone app. Unlike the other app extensions, the WatchKit app doesn’t run on your phone. In fact, it’s not even compiled against the iOS SDK. Instead, it’s copied to the watch when you install the watch app, and it’s run on the watch. Instead of iOS, it’s built for watchOS. The WatchKit extension is responsible for all communication between your phone and the watch, but it doesn’t manage the user interface of the app at all. Instead, it communicates with the other folder group in the template: the WatchKit App.
If this is your first experience writing apps for the Apple Watch, this separation of app code and user interface resources may seem arbitrary or unintuitive. Why did Apple decide to partition the apps this way? We can trace it back to how WatchKit extensions and WatchKit apps worked on the first version of WatchKit, before iOS 9 and watchOS 2. Instead of the WatchKit extension being compiled for watchOS, as we have today, WatchKit extensions were compiled as regular app extensions in iOS. Instead of being copied to the watch and executing on its processor, WatchKit extensions were left on the phone, were run on the phone, and communicated user interface changes over Bluetooth to the watch. This had a significant performance impact on the apps, but had an advantage in battery life for the watch—the heavy lifting of computation for the app was handled entirely on the phone.
The WatchKit App’s folder is pretty sparse at this point: your Interface.storyboard file, some placeholders for image assets, and an Info.plist. No code in sight. Crucially, however, all of the watch app’s UI will reside in the WatchKit App portion of the project. Instead of creating UI objects in code, you’ll put them in your storyboard, and your code will instruct the watch app on how to use them. This setup is a pretty severe departure from the way things work in iOS and is the model–view–controller paradigm taken to the extreme: your model and controller classes are separated entirely from your views.
WatchKit is the brains of this operation. The interface objects you use in your WatchKit extension are not the same as the objects drawn in the WatchKit app; they’re representations thereof and have some nifty behaviors. To conserve power, multiple updates to your UI are coalesced into one. If you update the text of a label 15 times in one method call, that’s fine; only the last value will appear on the label (though that would still be a code smell). You can think of interface objects in the WatchKit extension as proxies to their WatchKit app counterparts, even though they’re on the same device. In the end, the iOS app, WatchKit app, and WatchKit extension are packaged into one bundle in the iOS App Store, making the installation process for users simple. Before you ship to the App Store, you’ll probably want to test your app on a real Apple Watch, and for that, you’ll need to do some code signing.
18.191.233.15