Writing New Code in Swift

Brent Simmons on deciding to write new code in Swift:

And there has to be a time limit. I forget who proposed the 45-minute rule for CSS, where you give up and just use a damn table for your layout. I don’t want to be too quick to punt when using Swift, because it means I won’t be learning as much as I could be (and I need to become expert: that’s the point), but I also can’t let my productivity go too far from what’s normal.

I’ll give myself two hours of banging-head-on-disk, then punt. As a rough guideline. (I’m not actually going to use a stopwatch.) This number may change, but it’s important to have some limit as I’m doing this.

Sounds like a great approach to me.

Reading the Size Class Tea Leaves

I got thinking about size classes in iOS 8 after the Apple Watch announcement. As of right now, there are two size classes in each dimension: "regular" and "compact." Broadly speaking, the compact size class desribes the iPhone, and the regular size class describes the iPad. Yes, I know that there's not a strict mapping between size class and device, but there's enough of a connection that we can mostly use size classes as a proxy for devices. (The iPhone 6 Plus muddies the waters here a bit.)

When they were announced at WWDC, I was surprised the classes weren't "regular" and "large" – regular for the iPhone and large for the iPad. That's even more true with the introdution of the Apple Watch. It's easy to imagine creating a size class matrix like this:

Size Class Compact Regular Large
Device Apple Watch iPhone iPad

But instead, I think the Apple Watch implies something like this:

Size Class ??? Compact Regular Large
Device Apple Watch iPhone iPad ???

There's two things to consider here:

  1. Does the Apple Watch really fit into a size class smaller than "compact," and/or does it use size classes at all?
  2. Does the use of "regular" as the biggest current size class imply the existence of a "large" class in the future?

Where does the Apple Watch fit?

Apple hasn't released nearly enough technical information about the Apple Watch to talk about this with much certainty. Paul Sprangers made some educated guesses that the Apple Watch screen is roughly 280 x 350px, which would seem to place it in a size class smaller than "compact." Maybe this implies a new size class. ("Micro?")

It could be that the Apple Watch exists outside the size class system entirely. Apple's web site makes reference to something called the "Watch OS." We don't know much more about it than that, but even if it's distinct from iOS, it's likely to be strongly related. The odds are high that it's using size classes under the hood somewhere, even if it's not exposed to developers by name. After all, why create a system for flexibly adapting to different screen sizes if you're not going to use it on a new, differently-sized screen?

Either way, we'll know a lot more about this once we get a look at WatchKit.

Something bigger?

Both the iPad Air and the iPad mini have a "regular" size class in both dimensions, which implies that Apple is at least leaving room for something larger than the iPad. The likeliest explanation is that they're keeping their options open for shipping larger devices in the future. Maybe a larger "iPad Pro"? Or perhaps an Apple TV SDK, in which the TV has a "large" size class. Time will tell.

Should I Get a New Phone: iPhone 6 Edition

Yesterday Apple introduced two new iPhones, which means it's about that time when people to start asking me what phone they should buy. Since I often find myself repeating similar advice to a lot of people, I thought I'd jot down a few thoughts.

iPhone 6 or iPhone 6 Plus?

The newest models come in two sizes: the iPhone 6 at 4.7" diagonally, and the iPhone 6 Plus, weighing in at 5.5". By comparison, the iPhone 5 and 5S both measured 4.0" on the diagonal. Both phones are offered in 16GB, 64GB, and 128GB capacities.

Both new models share a lot of the same components: an updated screen, somewhat faster processor, and support for the new Apple Pay contactless payment system. In short, they're almost identical on the inside. There are only a key few differences between the two:

  • Screen Size: Obviously, the iPhone 6 Plus is significantly larger than the iPhone 6.

  • Battery Life: Apple says the iPhone 6 Plus gets somewhat longer battery life than the iPhone 6. For example, they claim 12 hours of LTE web browsing on the 6 Plus, versus 10 hours on the 6. We'll have to wait until these phones are actually released to know how they do in real world situations, but it's probably safe to say that the 6 Plus will last a bit longer on a charge. (More details on battery life comparison are available on Apple's web site.)

  • Optical Image Stabilization: The two phones share most of the same camera technology, but the iPhone 6 Plus also contains optical image stabilization as well. Apple says that it will result in clearer pictures in low-light situations.

  • Price: All iPhone 6 Plus models cost $100 more than the equivalent iPhone 6 model. For example, the 16GB iPhone 6 costs $199 (on contract), while a 16GB iPhone 6 Plus will set you back $299.

My advice on choosing between them? It really comes down to personal preference. I don't think the image stabilization will be a big deal for most users, and the iPhone camera is already quite good for a phone, so I think we can mostly set that aside. I also doubt that the battery life between the two models will be different enough in real world use to be noticeable for most people. That said, if battery life is a big issue for you, that might tip the scales in favor of the iPhone 6 Plus.

Primarily, I think the choice comes down to the size and price. Do you like very large phones, and is a bigger screen worth an extra $100 to you? Or would you be happier with a somewhat smaller (but still bigger than the iPhone 5S) phone that has more storage? Keep in mind that the iPhone 6 is already larger than last year's iPhone 5S. For the sake of comparison, here's a quick photo I snapped showing the relative sizes of an iPhone 5, iPhone 6, iPhone 6 Plus, and iPad mini:

iPhone 5, iPhone 6, iPhone 6 Plus, and iPad mini

Personally, I'm not a fan of really giant phones like the 6 Plus. Additionally, over the past few months I've run out of space on my 16GB iPhone 5 time and time again. I'm fairly certain I'll end up buying a 64GB iPhone 6.

Keep My Old Phone?

I usually buy a new phone every other year. I bought an iPhone 4, skipped the 4S, bought the iPhone 5, and skipped the 5S. In large part, that's because I'm not willing to pay full price for new phones, and every two years feels about right to me. However, I do advise people to buy iPhones early in their life cycle. For example, if you're going to buy an iPhone 6, get it this fall instead of waiting until the spring. If you buy a phone in spring 2015, for example, you probably won't be eligible for a new carrier-subsidized phone until spring 2017. Then you have to choose whether to buy another new phone that's been out for six months, or wait unil the fall.

Furthermore, it used to be true that iPhone releases in even-numbered years were the "big" updates (iPhone 3G, iPhone 4, iPhone 5) and odd-numbered years were more incremental updates (3GS, 4S). That pattern has subsided a bit in the past couple of years, so I'm not sure it's worth worrying about anymore. For example, you could argue that the iPhone 5S, with its powerful processor upgrade and TouchID sensor, was a bigger upgrade from the iPhone 5 than the iPhone 6 is from the 5S. Basically, if you're eligible for an upgrade when new iPhones come out and you like the new models, go for it.

Of course, if you like your current phone and it's running great, you can always hang on to it. Just remember, it's extremely unlikely that there will be any new phones from Apple between now and next fall. iOS 8 will run on phones back to the iPhone 4S, although it's likely to be fairly slow on the oldest devices. My guess is that it'll run just fine on an iPhone 5.

Automatic Headers in Swift

Unlike Objective-C, Swift doesn't have a concept of header files. In a lot of ways that's great, because it eliminates a lot of unnecessary typing and repetition. However, I find myself missing headers because they were a great way to get an at-a-glance look at the public interface to a class. Consider the following Objective-C header:

The header defines a Message class with a number of properties, as well as a method for replying to the message and a class method for downloading all messages. It's easy to tell from looking at the header what functionality it exposes to other classes without needing to worry about how it's implemented. The header also hides any private variables that other classes don't need to know about and don't have access to.

In contrast, here's the same class re-written in Swift:

The Swift class intermingles the interface and the implementation, as well as public and private properties and functions. We can see all the guts of what the class does under the hood, even though that's not relevant to someone who just wants to use the class. Moreover, it's conceivable that some of these functions would be long. (I've omitted an actual implementation here for the sake of this example.) That means a lot of scrolling and scanning through code just to see what functions are available.

In order to make this easier, I propose that Apple add a new view to the Assistant Editor in Xcode. This view would display an on-the-fly public "header" for the Swift file in the main editor pane. The header would only contain public (and maybe internal?) methods, as well as function signatures. Something like the following:

As you can see, it's very similar to an Objective-C header. However, we didn't actually have to write it manually, and there's no actual file associated with the header. It's just a view of the class generated by Xcode for convenience. This view would be uneditable, and would be automatically updated by Xcode as the Swift code changes. In practice, this would be a lot like developing in Objective-C using the "Counterparts" mode in the Assistant Editor to display header and implementation side-by-side. In short, the "header view" would give developers all the benefits of headers without actually having to write them.

UPDATE 9/6/14: I've filed a radar requesting this enhancement. Please consider duping!

CloudKit's Advantage

Greg Pierce responded to my earlier post with a great explanation of why he chose CloudKit for the next version of Drafts:

Why am I willing to make these trade-offs for CloudKit, despite it’s limitations? Because, ultimately, developer perspectives aside, I felt it was the right choice for my customers.

They will not need to setup another account with yet another set of credentials to manage. More importantly, their data will be stored with Apple, a vendor they have already choosen to trust. It will be stored in siloed, private data stores that not even the developer can access. That cannot be said for apps using Azure, Parse or other backend services.

This is one of the biggest reasons I want CloudKit to succeed. As a user, it's easy to get started with a CloudKit-based app because you (presumably) already have an iCloud account. That means more time exploring the interesting and unique things the app can do, rather than messing with accounts and credentials. And the privacy aspect is significant. I'd argue that Apple takes user privacy more seriously than any of its competitors. (Whether you agree with that or not, Greg is certainly right that users have chosen to trust Apple with at least some of their data by virtue of creating an iCloud account.)

However, these advantages may also limit some of CloudKit's possibilities. As I describedin my earlier post, the inability to move data off of CloudKit is one of my key concerns. While it's conceivable that Apple could add data export to CloudKit in the future, it's hard to imagine how they'd do so without compromising privacy. It's possible export could be limited to public data, but that might limit the utility of the feature in the first place. (For example, suppose Vesper used CloudKit at launch, but then decided to move to another service. It wouldn't do them much good if they couldn't migrate everyone's notes, which would presumably be stored as private data.)

As Greg pointed out, CloudKit holds a lot of potential benefit for users as well as developers. On the other hand, users won't see much of that benefit if few developers adopt it. Hopefully Apple has (or will) strike the right balance so that we all reap the rewards.