There’s been a lot of trepidation around the Apple Watch SDK, announced at the WWDC last June and released just recently.
This is just the first round, with limited functionalities. Apple Watch v2 will follow, but not that soon - so forward-thinking iOS developers should be prepared to wait for a few months.
The feeling among developers is extremely diversified. A lot of iOS developers are disappointed by many limitations imposed by Apple Watch SDK and its features. On the other side, many of us are excited, while others are not too far from a neutral position. But, after all, everybody is apparently happy to have a new toy to play with.
One thing that catches the eye, is how Apple Watch users are referred to. They are not users or mobile users, nor watch users or (with a pinch of originality) watchers. They are simply wearers. A term that sounds a bit weird, because if a user uses, implying that he interacts, a wearer wears, and that sounds like a passive usage. Of course, the Apple Watch is far from being a passive device. It combines the traditional features of a watch with more advanced options enabled by modern technology, especially when used in combination with an iPhone. It was not that long ago when phones started to become much more than just phones - history is repeating itself.
However, at the end the wearer name appears to be a smart choice. At least when writing user stories I don’t have to specify “As an Apple watch user I want to …” in full, I can just shorten that to “As a wearer, I want to …” - less ambiguity.
Device and UI
Omitting all Apple Watch features not strictly related to development, the most important problem designers and developers have to deal with are sizes - in fact there are 2 different Apple Watch models:
- 38mm screen with a 272x340 px resolution
- 42mm screen with a 312x390 px resolution
with a retina display in both cases.
Needless to say, it’s on iOS developers to assure that application looks good on both versions.
Apple Watch Connectivity
The Apple Watch communicates with the companion iPhone via Bluetooth 4.0, and it’s also NFC enabled. Apparently, it has no WiFi connectivity. Although it can tether via the iPhone and use both, WiFi and cellular data connection. But in a press info Apple clearly states that it also features Wi-Fi 802.11b/g.
User interaction (or wearer interaction, if preferred) can occur in 4 different ways:
- simple touch: a tap on a button is a typical example
- force touch: activated by applying more force when tapping and holding the screen. Similar to the right mouse click on a PC it will display a contextual menu (containing up to 4 items)
- gesture: vertical swipe to scroll, horizontal swipe to navigate between pages, left edge swipe to navigate back
- digital crown: hardware input used for fine tuned scrolling
There are some limitations regarding the user interaction, in particular about gestures:
- they are predetermined, so custom gestures are not supported
- multi touch is not supported, so no pinch to zoom or similar gestures requiring more than one finger
Here is the sample of contextual menu from the Apple WatchKit Guide.
Speaking of the Apple Watch UI, there are several limitations imposed by the reduced screen size, by design choices, and in many cases as a natural consequence of the underlying hardware. We expect that some of them will change for the better in future releases of the SDK, although it’s not possible to anticipate nor forecast what will actually change.
The first limitation is about how user interface is implemented: via storyboards only.
Apple Watch Navigation
WatchKit offers two mutually exclusive ways of navigating among the views of an Apple Watch app:
- a hierarchical navigation model, similar to the one used in iOS, with views stacked up during navigation
- a flat page based model, where the user can navigate between pages by swiping left and right
Unfortunately, combining these two navigation models in the same app is not possible. One of them must be chosen and used throughout the whole app.
However, any interface controller can present a modal interface controller, which can either be a single interface controller, or multiple interface controllers, arranged using a page navigation model.
There are 11 distinct interface components:
- date: automatically displaying the current date or time
- timer: displaying a countdown timer, automatically updated
- group: a container for one or more child components
- map: displaying a non interactive map, optionally with max 5 annotations
The group component can be used to combine Apple Watch UI elements in either a vertical or horizontal layout. Elements will be automatically laid out depending on their size. Some degree of flexibility is available here, given that groups can be nested.
Unfortunately, the auto layout is not available. But, considering that the user interface is much simpler compared to the iOS counterpart, it’s probably not a big loss.
For lists, the table component creates and manages content using a single column model, just like the
UITableView. However, it is not using the delegation pattern - the data source is directly provided to the table by specifying the number of rows first, and then initializing the content of each row in a for loop. On a positive note, it’s still possible to use custom table rows (i.e. cells in the iOS jargon)
Glances are read-only, single page, and non scrollable views, used for showing a snapshot of a timely and relevant app-specific data. No user interaction is allowed, except for the tap event. Tap on the glance will simply launch the app, optionally providing a context to let the app display a specific interface controller.
For example, an Apple Watch weather app can use Glance to display current temperature, location etc. By tapping it, the app opens, showing more detailed information.
Here is the sample Glance from the official Apple WatchKit Guide.
To read more about Glances please check the WatchKit Programming Guide.
Apple Watch Notifications
There are 2 notification types: short look and long look.
The short look notification is used to alert the wearer that something has happened, and it is automatically dismissed when the wrist is lowered. The layout is very simple, and consists of the app icon, the app name, and the notification title.
Keeping the wrist raised for some time, or explicitly tapping the short look notification, will turn it into a long look notification. This type of notifications provides more details, and supports user interaction via customizable buttons. These buttons can send notifications to the application. Unlike short notification, user must explicitly dismiss a long look notification by tapping a button that is automatically displayed at the bottom of the view.
More information about using Apple Watch Notifications can be found here.
Downloading an Xcode version supporting the WatchKit (currently the 6.2 beta version), and trying to get started with a WatchKit project without reading any documentation, a developer could feel confused because there is no WatchKit template:
There is no standalone watch application and a Watch App can only be added as a new target to an existing iOS application.
The reason for that relies in the architecture, and the way the watch app interacts with the related iOS app:
When the app is launched on the watch, the companion iOS extension is automatically launched. They both work in synergy, with the watch app showing content to the wearer and responding to interactions, while iOS extension is doing everything else. Actually, no application code is executed on the watch: all processing is delegated to the iOS extension.
This model closely resembles the browser <-> web application model, where the domain logic is performed at server side, and the client side is responsible for showing content to the user and responding to user actions.
The Watch App, that is installed on the device, consists of the storyboard and all related static resources, packed in a bundle. This bundle is static, meaning that adding or changing any of the resources, views, images etc. is not possible at runtime.
This static client-server model imposes several limitations on the iOS developer that wants to add a Watch app to their repetoire, and it’s probably one of the primary reasons why some developers didn’t react positively. Another popular remark is about animations: they are simply unsupported. The only way to mimic an animation is by packing individual frames into the watch app, and then simulating the animation by displaying images in a sequence. Good news is that by naming frames sequentially you can automate the animation directly from the Interface Builder, although the same can be done from code with a single invocation of an image control method.
However Apple has already announced that a new version will be released sometimes next year, with support for native applications, for which there are no further details yet.
The Apple Watch Framework: A Quick Look
WatchKit doesn’t use, inherits or specializes UIKit. A new framework has been implemented, specifically designed, and optimized for the watch, for its tiny display and for the limited hardware. The framework consists of 15 classes only, 12 of which are UI components (label, button, etc.).
The most important class exposed by the framework is
WKInterfaceController, which is the WatchKit counterpart of
UIViewController. So what in iOS (and OSX) is called the view controller, in Apple Watch is an interface controller.
Without digging too deeply, the most noticeable improvement over UIKit, from an Apple developer’s perspective, is the establishment of a pattern to pass data between interface controllers. A quick look at the initializer:
init(context: AnyObject?) // context from pushing controller or nil
reveals that it’s possible to provide an arbitrary object to an interface controller instance (called the
context in all APIs), simplifying and standardizing passing data from one interface controller to another. The only downside is that the object is not of a generic type, but an opaque
AnyObject which must be downcast to the expected type inside the initializer of the destination interface controller. That’s probably a trade off for still having (and probably also wanting) to keep using Objective C.
The interface controller life cycle is simplified if compared to the view controller counterpart, consisting of 3 transitions only:
init: invoked when the object is instantiated
willActivate: invoked when the content is about to be displayed
didDeactivate: invoked when the interface has just been hidden
Besides showing content to the user, the interface controller is also responsible for:
- handling user interactions
- managing a contextual menu
- coordinate handoff activity
- respond to notification
Is Apple WatchKit Ready?
With the several limitations, the watch kit may appear as an immature product. And in reality it is. It doesn’t support native watch applications, not to mention that there is no watch device in the market yet, so developers are still unable to test their apps and have a real feeling and feedback of how the app works.
Ok, there’s a simulator, which actually is not an independent simulator, but accessible as an external display to the iOS simulator (via the Hardware -> External Displays menu). But a simulator never replaces a real device - good during development and for debugging, but not enough.
The WatchKit is just a preview, a beta version, an appetizer, which is going to evolve with every new release. iOS developers have got the first version, let’s play with it and let’s try to get the most out of it.