App Launching on Apple Watch

Let me start by saying that I am very excited about watchOS 3. If I could have made a list and told Apple, "Here are the improvements I would like to see made to watchOS at WWDC this year" then I would consider that list to be thoroughly crossed off. A focus on performance, background updates for workout apps, and ditching the Friend button in favor of the new Dock are exactly what I wanted to see.

A lot of people watching the announcements caught that one notable Apple Watch feature was omitted from the commentary. The App Launcher, or Honeycomb / Home Screen, wasn't mentioned in the keynote or subsequent discussion about how users interact with Apple Watch. The subtext is clear. I don't think Apple intends or expects people to interact with their watch by launching apps from the Honeycomb any more than we do.

It's still clear that launching third party apps on the watch is very important. The Dock is a big step forward here but it can't be the only answer. The Dock is a more concise list of apps than the Honeycomb is, but the only context its aware of is which apps were launched recently or that the user favorites. The Dock is glance-able and meant to keep apps visible and freshly updated, but it's still not as easily accessible as the user's watch face with all of their complications.

It's been clear for several months that complications truly are the best app launchers. That's why the new ability to easily swipe between watch faces is absolutely game changing for Apple Watch despite not being something I was expecting. Next to the flashy new Dock it's an easy thing to miss, but I think it will have the biggest impact in how I interact with apps on my Apple Watch. 

The Apple Watch apps that I launch regularly are ones that I have complications visible for. I routinely use two fitness apps, UA Record and Runtime, because their complications are so easily accessible to me. The only time I go deeper into the Honeycomb is to launch apps that I don't have room to show their complications...like Stopwatch, or Timer. I choose not to keep their complications visible on my watch face because they usually don't have any content that is contextually relevant to me.

The significance of complications being the best way to launch apps is why swiping between watch faces is so valuable. It allows users to literally switch their context on the Apple Watch. One day this could presumably happen automatically, but at least it only takes one swipe to switch from your primary daily watch face to one with the type of information you want to have at a glance in another context.

This is going to completely change the way I use my Apple Watch. I'll be experimenting with this for a while in the coming weeks, but for now I've created three watch faces that I intend to switch between depending on what I am doing:

- Cooking
- Daily Activity
- Distraction Free / Movies

I love using the Stopwatch and Timer apps while I'm cooking or brewing coffee, but I don't want their complications visible during the rest of the day. The ability to swipe left and bring up an entire watch face devoted to them and any other complications relevant to cooking is a game changer for me. I'll keep my existing primary watch face configured with the date, and a few activity / fitness complications, and I'll also have my Movie watch face with no distractions that Ryan Considine inspired me to use.

Apple clearly intended for this usage pattern to take hold when designing watchOS 3. Craig Federighi stated so himself in tonight's live episode of The Talk Show in San Francisco. Watch faces are the true app launcher for watchOS, and users will start to customize their watch faces based on the contexts that are most important to them. This is where I could see some really exciting things happen with the platform. Collections of activity and fitness complications seem very likely to become popular, as well as watch faces with complications related to travel. I hope Apple will use curation to promote this concept and apps with great complications because of how much better this will make the experience of using an Apple Watch.

This is a really exciting week for watchOS developers. This is where the platform really starts to take off and we start to see what people will really do to build amazing watch apps.

The Twenty-First Floor

Lately I've been following along on the Swift conversation about static and dynamic features and the importance of the dynamic runtime. I'd like to share some of my thoughts as a developer who is using both Swift and Objective-C on an almost daily basis.

The concept of using the right tool for the job is a bit of a cliché, but it describes my views on the static nature of Swift very well. I like that we as developers for Apple's platforms have great options on both ends of the spectrum. Swift is an excellent static language, and Objective-C and the associated dynamic runtime is a great tool as well. I haven't found myself only wanting to use one or the other.

Maybe the point of Swift is to have a strongly-typed static language to use for the things that should have compile time type checking, like building application layers. Having the capability to build your application in a type safe environment while still leveraging a sophisticated dynamic runtime that supports tools and behaviors that make our applications easier to build feels like a huge advantage to me.

I think Swift is a great language and I've been enjoying using it to build applications and internally used frameworks. A team I work with just shipped an app built entirely in Swift with a 0.0% crash rate. There's a lot of places where using a static language makes sense, and I'm not ready to judge Swift's future based on whether it could be used today to replicate UIKit, Core Data, or any other Cocoa frameworks.

The measure of Swift's success shouldn't be whether or not it eradicates Objective-C from our tool chain. Honestly, I don't think that it should. The value it is adding to our existing tool chain as a foundational component, and the capability it brings to build highly sophisticated and powerful tools like Interface Builder and Core Data earn it a place in our tool kit for a very long time to come.

I liked this quote from Manton's blog post about Apple's mindset on Swift dynamic features:

Remember when Steve Jobs came back to Apple and compared NeXTSTEP to constructing a building by starting out on the 20th floor, with so much of the foundation and common patterns already taken care of for you? Cocoa allowed apps to be built significantly faster than before. Steve said at Macworld Expo in 1997 that the goal was to “eliminate 80% of the code that every developer has to write for their app.”

I love this, because I think the building metaphor applies really well to where we are with Objective-C and Swift. The building is Cocoa, and we don't need to re-build the first 20 floors. What's great about the static nature of Swift is it gives developers an option to make that last 20% of code type safe, faster, and more expressive. For a lot of applications and use cases, that's a really great tool to have.

–––

As a brief aside, I know that Swift has a lot of promise in areas with no history of a dynamic runtime, like Linux or perhaps even with embedded devices. I'm not trying to diminish that, or imply that Swift has to exist on top of Objective-C. I'm actually very excited about all of those areas and hope that Swift becomes widely used on other platforms. But I won't mind if much of the core platform for Mac and iOS continues to rely on the dynamic runtime.

Designing in Swift

I've been slowly easing into Swift over the past few months. Some projects I've helped with at work have been in Swift, and my last personal app, Picturesque, was written completely in Swift. I've really enjoyed using the language, but until recently hadn't designed a major new component from the ground up in Swift. Fortunately, last year at WWDC I think we got a great primer for doing this: Protocol Oriented Programming.

I've been attempting to follow a protocol oriented methodology, and so far I've really enjoyed it. The rule of thumb I've been trying to follow is not to use classes for anything. It's obviously possible to take this rule to the extreme, but I think it is a good standard to start by for learning how to design in Swift.

Without using classes (much), you're left with Protocols, Protocol Extensions, Structs, and Enums. I'm going to cover how I am currently using each of these in my design.

Protocols

Protocols are, of course, the primary interface to what I am building. They represent the capital-T Types that another developer would be interacting with, and the methods they would be calling. But they also represent the plumbing between internal components. 

For a message passing framework there are public facing protocols like Listening, and internal protocols like Persisting or Encoding. Since Protocols are also just Types, the Listening protocol can have a reference to the Encoding Type that its implementation can use to decode a message. This form of dependency injection has always been a good idea, but the reason this is so useful in a Swift design should become clear below.

Protocol Extensions

Not only can Swift protocols inherit from other protocols, but they can also be extended to provide a base implementation of their methods, or add new ones. Using this feature to provide a base implementation of a common protocol is a huge deal for Swift. You know exactly what I mean if you've ever defined a protocol in Objective-C that many classes implement, and had to copy-paste the same method implementation between all of them.

I'm also using protocol extensions to drive out the dependency injection scheme described above. Since a method implemented in a Swift protocol extension has very limited access to Self (after all, this isn't a Class implementation), you have to make sure that anything that implementation needs is available from the protocol definition. 

That's why having your protocol reference other Types, like an Encoding type, is so useful. Those referenced types end up forming the shared base implementation of the protocol. If your varying implementations of the protocol need to change the behavior of one of the base methods, they won't override the method, they'll just override that dependency instead.

Structs

One nice thing about structs is that they're really not intended to mutate. Once I find myself starting to insert mutating keywords in front of method definitions I start to think through A) whether or not I should just use a class, or B) does this method really need to be changing state after all? Many times, having a struct (instead of a class) implement a protocol has helped me make better decisions about how my methods handle object state, which I think makes me more careful when adding or changing state. Of course, structs shouldn't be encapsulating state anyways, which leads us to:

Enums

Enums are my favorite feature of Swift. I don't think we could have asked for a better tool to manage state and branching in our programs. Enums can have methods, hold associated values, and conform to protocols. Their initializers can even take parameters. They're beyond cool.

One of the ways that I use enums is to support different behaviors for different cases - a common programming problem. I have an enum conform to various protocols that can return a Type. A message passing system could use an Enum to represent the form of messaging, which could return a different version of the Encoding type for each case. Other implementations only need to hold onto the current case in order to receive an Encoding type for that case, and don't need to care about state. All of that is managed by the enum itself. Generally speaking, if you start to define a switch statement outside of an enum, consider just using an enum instead or adding your functionality to the existing enum.

Conclusion

We're still in the early days of discovering what makes for good design in Swift. From what I've seen so far, I'm very excited about adopting a protocol oriented methodology and continuing to learn more about good code design in swift.

Swift is clearly a language that presents us with a lot of options from a design perspective. Once we get accustomed to protocol oriented programming, the next big decision to master is going to be when to use reference types (classes) versus value semantic types (structs, and enums). That's a decision we really weren't accustomed to making regularly with Objective-C, but one which presents a whole new set of options to consider in Swift. I don't have an answer for this one yet, but stay tuned for a future blog post.