WatchKit
Everyone is excited aboutᴡᴀᴛᴄʜ. Developers especially.
What’s the best way to get started? Look no further thanApple’s WatchKit developer resources.
- Watch the “Getting Started” video—it’s like being in Moscone.
- Read theHuman Interface Guidelines—consider it a prerequisite for designing your application.
- Peruse theWatchKit Programming Guide andWKInterfaceCatalog for an introduction everything the framework provides.
- And when you’re finally ready to add that App Extension target to your app, consult theLister Sample App (in both Objective-C & Swift!) to see how everything fits together.
Apple’s Developer Publications, Developer Evangelism, and WatchKit teams knocked it out of the park with the WatchKit launch. The official resources are superb.
That said, after taking a look at everything, there were a few things that jumped out as it relates to UIKit. They’re the kind of subjective, opinionated things that don’t make for good documentation, but might be interesting or useful to anyone else as they’re getting started.
So this week, some initial impressions of WatchKit from the perspective of an iOS developer.
WatchKit harkens back to the earliest days of iOS development, when the platform limitations acted as liberating constraints for developers. Compared to OS X & AppKit, mired in decades of cruft and churn, iPhoneOS (as it was originally known) & UIKit were a breath of fresh air. Apps were small, simple, and humble.
After 7 years and as many major releases, iOS has grown to encompass myriad devices and configurations, from iPhones and iPads of all shapes and sizes, to the TV and CarPlay. It’s still an amazing developer experience (for the most part), but it feels like some of the magic has been lost along the way.
Counterpoint: Nostalgia is bullshit. Remember, back in those days, there was no ARC, no GCD, no Interface Builder support for iOS and certainly no Swift. The indispensable open source libraries of the time were Three20 and asi-http-request. The state of the art for table view scroll performance was to manually composite text and images in a cell’s content view
draw
. Life was solitary, poor, nasty, brutish, and short.Rect:
Regardless of where you’re personally coming from, the simplicity of WatchKit is something to be enjoyed and celebrated.
Comparison to UIKit
WatchKit bears a striking resemblance to UIKit, which is not entirely surprising, given their shared history and purpose. Watches are different from phones and tablets, which themselves are different from desktops. Some concepts are shared, but each have unique purposes and constraints that shape the topography of their software.
For sake of comparison, here is how one might understand WatchKit in terms of UIKit / Cocoa concepts:
WatchKit | UIKit |
---|---|
WKInterface | UIView |
WKUser | UIApplication +UIAlert |
WKInterface | UIDevice |
WKInterface | UIView |
WKInterface | UIButton |
WKInterface | UILabel +NSDate |
WKInterface | UIScroll |
WKInterface | UIImage |
WKInterface | UILabel |
WKInterface | MKMap |
WKInterface | UITable /.separator |
WKInterface | UIStepper +UISlider |
WKInterface | UISwitch |
WKInterface | UITable |
WKInterface | UILabel +NSDate +NSTimer |
As anamespace prefix,
WKInterface
sticks out like a sore thumb, butWK
on its own was recently claimed by the newWebKit framework. Although the Watch platform is a long way from being able to embed web views, the decision to demarcate things as they are is sensible.
There’s a lot of overlap, but there are important differences. Understanding those differences is both informative to making great WatchKit apps as well as enlightening in terms of how Apple’s thinking about API and best practices continues to evolve.
WKInterfaceController
WKInterface
manages the elements in a scene, whereasUIView
manages a view and its subviews. Interface objects are not views, but they act in similar ways.
The designated initializer forWKInterface
isinit
, which accepts an optionalcontext
object:
overrideinit(context:AnyObject ?){super.init(context:context)…}
What’s acontext
? It’s anything you want it to be: a date, a string, a model object, or nothing at all.
The open-endedness ofcontext
may be disorienting at first, but it’s actually a remarkably clever solution to a long-standing problem of UIKit—namely, the difficulty passing information between view controllers. Without a standard convention for configuringUIView
s as they are pushed, popped, and presented, developers are regularly faced with a miserable choice between custom designated initializers (incompatible with Storyboards), property configuration (prone to creating controllers with incomplete state), custom delegates (overly ceremonious when done correctly), or notifications (just… no). It’s for this reason that so many applications backed by Core Data fall into the pattern of referencing a sharedmanaged
in the App Delegate.
But I digress.
Overall,WKInterface
’s API has a tiny footprint, and there’s no better illustration than its lifecycle methods:
// MARK: - WKInterfaceController overridefuncwillActivate (){…}overridefuncdidDeactivate (){…}
That’s it: 2 methods. No loading / unloading, no will / did appear / disappear, noanimated:YES
. Watch apps are simple by necessity. Communication between the iOS device driving the application and the watch is both time-consuming and battery-consuming, so all of the setup for the interface controller’s scene is to be done in the initializer andwill
. Both during and afterdid
, the Watch will ignore attempts to update the state of interface elements.
Watch applications are either Hierarchical or Page-Based. This is similar to Xcode’s project templates for “Master-Detail Application”, “Page-Based Application”, and “Tabbed Application”, except that the design choices are mutually exclusive.
Hierarchical applications have an implicit navigational stack, whichWKInterface
can manage with `-pushControllerWithName:context: &
-popController. One thing to note here is how
-pushControllerWithName:context:` takes a string—the name of the controller as specified in the Storyboard—rather than an instance of the controller itself.
Page-Based applications, on the other hand, act like a horizontal or vertical pagedUIScroll
, with a pre-determined number of scenes each managed by a controller. It will be interesting to see which use cases are best served by Page-Based and Hierarchical interfaces. Without trying out stock applications on a real device, there’s not much context to understand the trade-offs of each intuitively.
As a final aside, there is an interesting pattern in Apple’s Swift sample code, to use inner structs as namespaces for Storyboard constants:
classWatchListsInterfaceController :WKInterfaceController ,ListsControllerDelegate {structWatchStoryboard {staticletinterfaceControllerName ="WatchListsInterfaceController" structRowTypes {staticletlist="WatchListsInterfaceControllerListRowType" staticletnoLists ="WatchListsInterfaceControllerNoListsRowType" }structSegues{staticletlistSelection ="WatchListsInterfaceControllerListSelectionSegue" }}…}
WKInterfaceObject
WKInterface
resembles a streamlined rendition ofUIView
, with properties foralpha
,hidden
,horizontal
&vertical
alignment, andwidth
&height
.
The most striking difference is the lack of aframe
. Instead of manually specifying coordinate points or setting up Auto Layout constraints, WatchKit interface objects are laid out in a grid according to their margins and respective ordering, which is reminiscent to working with a CSS framework likeBootstrap (or for you Rubyists out there, rememberShoes?).
Another departure from Cocoa Touch is that Target-Action methods use a fixed-format specific for each type of control, rather than passing a dynamicsender
andUIEvent
.
Object | Action Method |
---|---|
Button | - (IBAction)do |
Switch | - (IBAction)do |
Slider | - (IBAction)do |
Table | - (IBAction)do |
Menu Item | - (IBAction)do |
For the small, closed set of controls, this approach is really appealing—much better than typingUIControl
.
WKInterfaceButton
WKInterface
is an interface object that can be tapped to trigger an action. Its contents can be either a single text label or a group.
That latter part—being able to contain a group—ishuge. This avoids one of the biggest gripes folks have withUIButton
, the difficulty of adding subviews and having things position and interact correctly, which would otherwise drive people to give up and useUITap
.
WKInterfaceTable
Of all of the concepts carried over from iOS, tables are perhaps the most-changed.
UITable
is the backbone of iPhone applications. As such, they’ve evolved significant complexity to handle the demands of applications with a lot of data that needs to be displayed in many different ways.WKInterface
, by comparison, seems marginal by comparison.
WatchKit tables do not have sections or headers, or footers, or editing, or searching, or data sources, or delegates. Rows are pre-populated atWKInterface
, with each row specifying its own row controller (anNSObject
subclass withIBOutlet
s).WKInterface
can respond to table interactions either with thetable:did
delegate method, or using the aforementioned Target-Action method.
It may not seem like much, but this approach is well-suited for the watch, and is a lot more straightforward than on iOS.
WKInterfaceLabel
By contrast,WKInterface
is perhaps the least-changed thing carried over from iOS. With support forNSAttributed
, custom fonts, and font scaling, it’s pretty much everything you could ask for.
WKInterfaceDate & WKInterfaceTimer
Let us not forget that time is a pretty important concept for watch. As such, WatchKit introduces two new interface objects that are unprecedented in Cocoa or Cocoa Touch:WKInterface
&WKInterface
.
WKInterface
is a special kind of label that displays the current date or time.WKInterface
is similar, except that it displays a countdown until a specifieddate
.
Including these two classes does as much to ensure app quality as much as anything else in WatchKit. Given how these essential these tasks are for a watch, and how notoriously bad programmers are at usingNSDate
andNSTimer
, one can only imagine where we’d be without these.
WKInterfaceSlider & WKInterfaceSwitch
Sliders and Switches are due for a comeback on the watch. Without the benefit of touch gestures, interfaces are resigned to go back to basics.Tap, Tap,On
/Off
.Tap, Tap,+
/-
.
WKInterface
&WKInterface
both appear to be well-crafted and rather customizable.
This is, of course, but a superficial reflection into the capabilities of WatchKit. Like I said at the beginning of the article,Apple’s official resources for WatchKit have everything you could ever need.