What It Takes to Enhance Your iOS App With Apple WatchKit

10 Dec 2014
How to enhance functionality of iOS App With Apple Watch. Lemberg Blog.

Pre-story

A couple of weeks ago, I started to work on quite an interesting and, let`s say, “pioneering” challenge, about which I am about to share my observations and findings with you now.

My challenge was to design a simple Apple Watch app providing the possibility to create and manage dates, display event countdowns, notifying the user about a certain date/time approaching, etc. Each date is also associated with a certain image picked by the user which is then shown as a part of the content of a glance warning that the event/date is approaching.  

What is Apple Watch?

Apple watch is a small “wearable computing” smartphone-type device that is able to run its own applications. These apps are extensions of some (containing) iPhone apps. The watch is a standalone device, but also definitely an addition to iPhone. At least that’s what it seems now.

Expectations

After watching the Apple Watch presentation, everyone was impressed with its style.

Personally, I was hoping to find all the features demonstrated in the “running”, “activity”, “world clock” apps in the SDK. These apps looked very fancy and it seemed like some of their functional controls would be accessible via Interface Builder as the default UI controls.

To learn more about creating apps for Apple Watch, visit developer.apple.com.

What I actually discovered

However, it appears that at the moment the functionality of the Apple Watch app is somewhat limited. Let’s just mention some of the most important things:

The navigation of the app can be of two types:

  • hierarchical (its a common stack of UI controllers. Sound optimistic for now. Nothing different from an iPhone app ;) )
  • page based

Everything seems fine with the navigation except that its not possible to use both of them within one app. Means these navigation types are mutually exclusive. So think in advance before you start implementing the workflow of your own. Also, there’s a possibility to present controllers modally from point of the app. This is a good novelty and can be extremely helpful.

Handling UI components can also be tricky ;)

  • You can’t add any controls in the run-time. Everything should be added to your InterfaceController during the design-time. If you want to add some stuff on the go, place it on the screen in advance with the alpha=0 and then change it to 1. (Note that making a control hidden will rearrange/re-layout the UI as if it were completely removed).

Sounds a bit complicated, right? ;)

  • You can manipulate frames of the UI controls directly. In fact, neither directly nor indirectly, you cannot do this at all. You can only change the size at run-time. The alignment, insets can be modified only in the Interface Builder.

Using images is obvioulsy different. The memory of the device is limited, and therefore you can only bundle 20 MB of images within your Apple watch app. There’s also simple caching introduced:

The countdown control can only be displayed in one of the predefined formats listed in the object inspector “Format” dropdown. We all wish we could do something like:

[countDownTimer setFormat: @”Time left: dd’Days’ hh:mm:ss”]. Unfortunately, that is not possible. Implementing such a timer firing NSTimer event sounds like a suicidal approach as it will probably drain the battery in an hour or so.

Outlets are normally created the way you used to do it in the iPhone/iPad storyboards, except for the fact that Outletcollections are missing. There’s simply no way to add Outletcollection. Also, the event handling selector for the Button click doesn’t have the sender object in its prototype. So if you have three buttons on a certain interface controller, you would probably want to define:

However, the selector for the button click doesn’t have a sender argument, its only -(IBAction) buttonClick so you will have to define each handler separately for each button.

Personally, I can’t see the logic behind for this, but it’s what we have in the SDK at the moment.

Extending/customizing the functionality / behaviour of a certain WKInterface control:

Subclassing doesn’t make sense as you simply won't be able to attach your outlets to this object. The “custom class” field in the object inspector at the storyboard is not editable so it doesn’t allow you to set any class there.

And famous last words about bundle ids:

After you create your Apple watch project and add a WatchKit target to it, you’ll have three targets:

  1. The contating project (normal iOS app) target
  2. WatchKit extension targer
  3. AppleWatch app target

(You’ll also probably have some default Test target which doesn’t have any relation to the problem decribed in this paragraph)

If you set the bundle ids later you should:  

  • check all three .plist files bundle ids so that it looks something like:
     
    1. com.company.appname
    2. com.company.appname.watchkitextension
    3. com.company.appname.watchapp
  • Make sure your AppleWatch app .plist (3) СompanionAppBundleIdentifier” value is the containing app bundle id. (The target number 1 bundle id)

Otherwise, you’ll get either a compiler error “Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.”, or some weird simulator error “Watchkit LaunchServicesError code=0”.

Summary

Overall, WatchKit provides great tools to extend the functionality of your iOS apps. One should realize that all the limitations, which you may at first dismiss as some unnecessary inconveniences, are in fact restrictions that allow you to properly handle battery usage. There’re also some known issues (some of them connected with simulator, some - not ). For example resentTextInputControllerWithSuggestions:completion: seems to be broken and doesn’t present anything on the screen. These issues are referenced at iOS 8.2 Release Notes.

The xCode 6.2 itself is beta so it’s not perfectly stable yet. The simulator works fine I would say, apart from getting stuck during the app launch sometimes. Simple force quitting and rerunning the app solves the problem. Two Apple watch screen resolutions are easily accessible from Hardware=>External Display menu.

Hope this post was useful for you. So, fear no more of Apple WatchKit and enhance your app functionality wisely.

Have something to add? I`d like to hear from you. Please share your thoughts or questions in the comment section below.  

For more information about the project I was working on check out Twenty8Watch showcase or read interview with FDThinking on Twenty8Watch App & Developing Apps for Smartwatches. If you are interested in developing applications for latest IoT gadgets I`d suggest to visit experience section Apps for Connected Devices.

SEE ALSO: