WatchKit for watchOS 2: Initial Impressions

WatchKit for watchOS 2: Initial Impressions
WatchKit for watchOS 2

WatchKit for WatchOS 2

Like Ray, I was unable to attend WWDC this year, but I’ve still been having an amazing time watching the videos, reading the docs, and discussing all the news with Jake, Nate, and the folks on the Tutorial Team.

As you may know from the podcast, I am a huge Apple Watch fan, so I was particularly excited about all of the goodies in watchOS 2.

I’ve been spending the last few days looking over the Apple Watch docs, so thought you might enjoy a quick overview of what’s new.

Please post any of your own thoughts in the comments below, and feel free to highlight anything I’ve missed!


Wait, did he just say native?

Wait, did he just say native?

Perhaps one of the biggest changes to WatchKit with this release is that you can now build native watch apps.

Unlike the previous version of watch apps where the interface ran on your watch but the code was executed on your iPhone, with watchOS 2 both reside and execute on the watch itself.

This has some very positive side-effects, such as making your apps launch quicker, and be far more responsive since there’s no longer a round-trip to your phone over Bluetooth LE with every interaction.

This move to native apps does also have some implications that you need to be aware of:

  • openParentApplication(_:reply:) has been removed from the SDK. But don’t panic, as it’s been replaced by the much richer Watch Connectivity framework. More on this shortly.
  • Sharing files using shared app groups is no longer an option. Again, you can use the new Watch Connectivity framework to facilitate this, but Apple has also provided network access for native apps in watchOS 2. So, if you were using app groups to share data pulled down from the internet, you can now do this directly on the watch using good ol’ NSURLSession.
  • iCloud isn’t available on the Watch.

Watch Connectivity

With the Watch Connectivity framework you can pass files and data back and forth between the watch and its paired iPhone. If both apps are running in the foreground, then the communication is live, otherwise it happens in the background so that the data or file is available when the receiving app is launched.

The main player in this new framework is WCSession, which handles all the communication between the two devices. You don’t create instances of this class yourself, but instead use the defaultSession singleton object.

To get up and running you simply assign an object that conforms to the WCSessionDelegate protocol to the session’s delegate property, and call activateSession(). If you plan on making frequent use of Watch Connectivity then I highly recommend you do this setup as early in your apps lifecycle as you can.

Once you have your session configured and activated, you can use any of the following methods to transfer your data and files:

  • updateApplicationContext(_:error) is used to transfer a dictionary of data to the counterpart app. This won’t always happen immediately, but will happen before the counterpart app wakes up so that the data is available at launch. The counterpart receives the dictionary via it’s session delegate’s session(_:didReceiveUpdate:) method.
  • sendMessageData(_:replyHandler:errorHandler:) is used to transfer data to the counterpart app immediately. Calls to this method are queued up and delivered in the same order in which you send them. If you’re sending data from the watch to the iOS app, then the app is woken up in the background if it’s not already running. If you’re sending data in the other direction and the watch app isn’t running then the error handler is called. The counterpart receives the data via it’s session delegate’s session(_:didReceiveMessageData:replyHandler:) method.
  • transferFile(_:metadata:) is used to transfer files, such as images, in the background. This behaves in the same way as the previous method, waking the iOS app up if it’s not running, or calling the error handler if the watch app isn’t running. The corresponding delegate method you need to implement to receive the file is session(_:didReceiveFile:).

There are numerous other methods provided by the framework, so I highly recommend you check out the reference.

See, didn’t I tell you not to worry about losing openParentApplication(_:reply:). :]

Other WatchKit Highlights

I’ve gone into detail on two of the biggest changes in this release of WatchKit, but there were several other highlights that I think are worthy of a mention.


While WatchKit still includes its original approach to animation, cycling through a pre-generated series of images, WKInterfaceController now provides support for basic animations that are more akin to iOS, via the new animateWithDuration(_:animations:). This takes a duration and a block, and animates any changes made to interface objects within that block over the provided duration. For example:

animateWithDuration(1) { () -> Void in 

You can animate changes to the following properties of WKInterfaceObject:

  • alpha
  • width and height
  • vertical and horizontal alignment
  • background color
  • layout group insets
Note: Animations aren’t supported in glances or custom notifications, and any changes you make in the animation block will be applied immediately without animations.

I realise this may seem a little rudimentary since there’s no way to provide a timing curve, or know when the animation is complete, but I’m sure you’ll agree that it’s definitely a step in the right direction, and I’m hoping Apple will build on this in future seeds.

More Access To The Hardware

WatchKit for watchOS 2 provides access to much of the devices hardware and sensors, including the Digital Crown, Taptic Engine, heart rate sensor, accelerometer, and microphone.

This opens up a whole new world of functionality for your apps, such as being able to accurately monitor the heart rate of a user of your fitness app as they work out, or use the Taptic Engine to provide a more immersive gameplay experience. I honestly can’t wait to see what you all come up with! :]

New Interface Objects

With this release of WatchKit Apple has shipped a brand new interface object: WKInterfacePicker. This presents a scrollable list of items, which you interact with via the Digital Crown.

The items in the picker can be text, images, or a mix of the two. When the user selects an item, WatchKit calls the picker’s action method passing the index of that item.

A picker can be displayed using one of three different styles:

  • List: this displays the items as a vertically stacked list;
  • Stacked: this displays the items like a stack of cards that animate in from the bottom of the picker as the Digital Crown is turned;
  • Image Sequence: this displays a single image from a sequence of images.

It’s also worth pointing out that a single interface controller can include multiple pickers.

And speaking of interface controllers, WKInterfaceController now exposes a method that allows you to present alerts and action sheets.

Calling presentAlertControllerWithTitle(_:message:preferredStyle:actions:) presents an alert or action sheet over the current interface controller, depending on the style you pass as the preferredStyle parameter. The actions parameter is probably the most interesting of the four, as this takes an array of instances of WKAlertAction, which themselves provide a block to execute when the corresponding button is tapped by the user. It’s also worth noting that you’re responsible for dismissing the alert or action sheet within these blocks.

One More Thing…

On the previous episode of the podcast, when Jake and I were discussing what we’d like to see announced at WWDC, one thing we both agreed would be a great addition to the Apple Watch was custom complications, which you can think of as little widgets you can install on clock faces. Well I guess Tim and co. must be regular listeners, as we asked and they delivered!

That’s right, you can now build custom complications for your watch app and have your data appear right on the user’s chosen watch face.

Custom complications are built around the concept of families, with each family providing one or more template classes that you subclass to implement your own complication. There are currently five families of complication:

  • Modular: there are small and large variants of this family, and they can be seen on the MODULAR watch face.
  • Circular: there is on a small variant of this family, and it can be seen on the SIMPLE watch face.
  • Utilitarian: like Modular, there are small and large variants of this family, and they can be seen on the UTILITY watch face.

See this guide for a more visual representation if you don’t have an Apple Watch or are unfamiliar with the available watch faces, and check out the Providing Custom Complications section of the watchOS 2 Transition Guide for more details on building custom complications.

Custom complications are probably the highlight of this WatchKit release for me, and I can’t wait to dive into the APIs and start building my own complications!

Where To Go From Here?

Overall, I’m pretty excited by all the new features in watchOS 2, and I look forward to working on the second edition of WatchKit by Tutorials with the Tutorial Team in the coming months.

Do keep in mind that this is only the first seed of WatchKit for watchOS 2, and as Apple releases future seeds it’s likely even more new features and APIs will be added, along with the things I’ve covered here changing or even being replaced with something even better – it’s happened before, it’ll happen again! :]

I’m curious to hear what your initial impressions on this WatchKit release are – please add your thoughts in the comments below.

WatchKit for watchOS 2: Initial Impressions is a post from: Ray Wenderlich

The post WatchKit for watchOS 2: Initial Impressions appeared first on Ray Wenderlich.



Write a comment