AILW: Immediacy

This is part of my ongoing As I Learn WatchKit series.


The need for speed.

As I begin doing the actual work of building out my apps’ WatchKit extensions, a topic that keeps coming to my mind is that of immediacy.

While every application I build always includes a consideration of speed. How fast each view can load, how fast I can render table cells, how quickly I can load and persist data. These considerations are typically rooted in a desire to make the experience of using the application pleasurable. I’m making things fast so that while you use my app it is responsive.

In a WatchKit application all those same considerations apply, but layered on top of them is a further requirement for immediacy.

The nature of interacting with something that is sitting on your wrist is very different than something that lives in your pocket. I don’t typically have momentary interactions with my iPhone. With the exception of reading a notification on my lock screen I can’t think of many interactions I have with my iPhone that take less than 30 seconds.

My suspicion is that Watch Apps will spend much of their lives being used well below that threshold. Raising my wrist to glance at something then immediately putting it down again. These interactions are fleeting and brief.

Apple mentions this concept in their Human Interface Guidelines.

A WatchKit app complements your iOS app; it does not replace it. If you measure interactions with your iOS app in minutes, you can expect interactions with your WatchKit app to be measured in seconds. So interactions need to be brief and interfaces need to be simple.

This means that I need to be extremely careful about how I’m building things so that I can get the user in-and-out of the app as quickly as possible.

Achieving Speed.

This concept is probably best explained via an example.

For my Feed Wrangler app extension I’m expecting to present the user with a list of articles from their unread feed. Something that looks vaguely like this mockup.

This will be a scrollable list within the main watch app and likely constructed into a digest format for the app’s Glance view.

There are a couple of different ways that I can structure the data provider for this view.

  • The simplest version would be to just make a web-service request asking for the latest articles, parsing the result and updating the table. This guarantees fresh data, is dead simple to implement but comes at a terrible cost. My initial testing could never get this approach to load the data (to say nothing of launching and populating the UI) any faster than a second (typically more like 2-3s). Not awful but certainly not immediate. Anything that involves a network request should likely be completely disregarded.
  • Use silent push notifications to keep the app’s internal Core Data stack fresh, then load directly from there on launch. This isn’t too bad. I was able to get this down to something like 0.1 seconds to load the data. This is pretty good to but still not the best we can do.
  • Use the same silent push notification setup to get fresh data loaded but add on an additional step at the end of a data import to prime a fast cache for the watch to use. My initial testing for this used a dead simple serialized NSDictionary for the cache. This can get the data load times down to 0.05 seconds.

Without having actual hardware to test, the difference between the later two approaches is difficult to evaluate. I don’t know how important that extra 0.05 seconds will be in actual use. However, my guess is that the difference between good and great watch apps is going to be the sum of a lot of tiny optimizations like that.

Anything that could show the user a progress spinner (however briefly) is a failure on my part.

David Smith




AILW: WatchKit Data Sharing (Video)

This is part of my As I Learn WatchKit series.

In order to create useful extensions it is vital that you share data with your main host iOS app. This video walks through the basics of setting up that sharing via App Groups.

As with my last video post, this is all still very new to me. So any feedback is appreciated.

David Smith




The Talk Show Bond Anthology

In this past week’s The Talk Show John and Dave respectfully tread into the hallowed Talk Show ground of discussing James Bond. Their discussion got me thinking about the segments Dan and John did talking through each movie back in 2011.

The James Bond movies are some of my favorite movies of all time. I remember very fondly following along with Dan and John each week as they made their way through the first twenty three films. Those conversations still stand as one of my favorite podcast series.

In 2012 (just before Skyfall came out) I had the notion to go back and re-listen to them all. Unfortunately since they were done as a segment inside of regular Talk Show episodes it was initially a bit tricky to find them all. However, once I was able to isolate them the re-listen was worth it.

As I was thinking about this all this week I realized that I had never shared the isolated tracks I had put together. Which seemed like an awful shame.

Below are each of their discussions and the associated The Talk Show episode. I hope you enjoy them as much as I have.


Dr. No (1962)

Episode: #24: Decoy Vodka
Listen

From Russia with Love (1963)

Episode: #25: Chess
Listen

Goldfinger (1964)

Episode: #26: The Worst Way to Get Cut in Half
Listen

Thunderball (1965)

Episode: #29: Spear in the Back
Listen

You Only Live Twice (1967)

Episode: #33: Extortion is my Business
Listen

On Her Majesty’s Secret Service (1969)

Episode: #34: A Very Puffy Shirt
Listen

Diamonds Are Forever (1971)

Episode: #35: I Wear My Jeans Real Tight
Listen

Live and Let Die (1973)

Episode: #37: Man in a Tub
Listen

The Man with the Golden Gun (1974)

Episode: #38: Ducks with Anger Problems
Listen

The Spy Who Loved Me (1977)

Episode: #39: Agent Backhair
Listen

Moonraker (1979)

Episode: #40: Gaucho
Listen

For Your Eyes Only (1981)

Episode: #41: Frigate
Listen

Octopussy (1983)

Episode: #42: Palming the Egg
Listen

Never Say Never Again (1983)

Episode: #43: Free Radicals
Listen

A View to a Kill (1985)

Episode: #45: Secret Horse-Doping Lab
Listen

The Living Daylights (1987)

Episode: #47: Nice Shirt, Handsome
Listen

License to Kill (1989)

Episode: #49: We Gave Her a Nice Honeymoon
Listen

GoldenEye (1995)

Episode: #50: Buttering Both Sides and #51: iPhone Jr.
Listen

Tomorrow Never Dies (1997)

Episode: #52: Keep It Secret, Dude
Listen

The World Is Not Enough (1999)

Episode: #54: Shenanigans
Listen

Die Another Day (2002)

Episode: #58: Detective Latchkey
Listen

Casino Royale (2006)

Episode: #60: I Tip Profusely
Listen

Quantum of Solace (2008)

Episode: #61: Worst Sleeper Agent Ever
Listen

I also bundled up the collection into a static RSS feed.

David Smith




AILW: openParentApplication:reply:

Apple just released Beta 2 of the WatchKit SDK. There are a few things that got updated, but by far the most significant update is the addition of a pair of methods permitting interactivity between the host and extension apps.

Like I mentioned in the previous link post one of the trickiest parts of building a WatchKit app is dealing with the concurrency between the host and extension. Jared Sinclair has a great pair of posts detailing some of these issues.

At their core, all these issues stem from needing a reliable method for coordinating the actions of the extension and the host app.

This is basically what Apple just introduced. I’ll let Apple describe how this now works by quoting from the updated section of the Programming Guide.

Communicating Directly with Your Containing iOS App

Apps that work closely with their parent iOS app can use the openParentApplication:reply: method to send requests to the parent app. App extensions run only while the user is interacting with the app on Apple Watch and do not support background execution modes. Parent apps have fewer restrictions and can be configured to run in the background or to gather information on behalf of the WatchKit extension.

When you call the openParentApplication:reply: method, iOS launches or wakes up the parent app in the background and calls the application:handleWatchKitExtensionRequest:reply: method of its app delegate. The app delegate can use the provided dictionary to perform any requests and return a reply to the WatchKit app.

I’m still doing some testing about what the full capabilities of this are going to be, but this is amazingly good news. There are a bunch of low level data management tasks that just got a whole lot simpler. There are now a whole bunch of application capabilities that just became possible.

We’ll likely never know if this functionality was planned all along or is a reaction to our Radars. I don’t really care. Either way I’m really excited about the change and encouraged to keep on filing my enhancement requests.

David Smith




» AILW Link: Introducing MMWormhole

I’ve been doing a ton of thinking about data persistence and message passing recently. Your main iOS app runs in a separate process with its own sandbox to your WatchKit extension. Which makes it quite tricky to keep your App and the WatchKit extension in sync without deadlocks, data conflicts, etc.

I had been starting to work on a mechanism to work around this by building a messaging mechanism between the two. The fine folks at Mutual Mobile just saved me the effort. Their MMWormhole library does exactly what I want. It is a dead simple messaging scheme for sending basic commands back and forth (in real-time if both are running).

I haven’t integrated with it yet but reading through its code it is 99% what I would have built so it seems extremely promising.

David Smith