Method Naming in Swift

I’ve been struggling to come up with a coherent response ever since I read Radek’s article on naming methods in Swift. While he makes a number of good points, I keep coming back to a deep-seated anxiety about moving toward shorter, less descriptive method names in Swift. The crux of my discomfort comes from this section of his post (emphasis mine):

Code is not made equal. It would be a mistake to apply the same naming convention to everything. Some methods are generic and broadly used. Some are rare or domain-specific.

Consider these functions and methods: map, reduce, stride, splice. These are very short and easy to remember. They’re not exactly self-explanatory, but that’s okay, because they are standard library methods that you’re going to use many, many times so the benefit of a short name is greater than the price of having to learn it first.

On the other side of the spectrum, there’s your application code. You probably don’t want to give methods in your view controllers obscure single-word names. After all, they’re probably going to get called once or twice in your entire codebase, they’re very specific for the job, and once you start working on another class, you’ll totally forget what the thing was.

I hope you see where I’m going with this. If you’re writing library/framework-like code, or some base class that’s going to be used throughout the app, it’s okay to use short and sweet names. But the more application-specific it is, the more you want clearer, more descriptive, intention-revealing methods.

I don’t think this logic pays enough attention to the fact that someone else will very likely be working with your code after you write it. Even if you’re a single developer, you might eventually pass that code off to someone else – maybe because you got a new job, or added a partner, or sold your app to another developer. Best practices are important because they help us make our code accessible to the next person who works on it.

I also think developers should take care to make a language accessible to people who are new to it. That’s especially true right now with Swift – we’re all new to it! Keeping the language accessible might mean trading off some conciseness in favor of descriptiveness. Consider the examples above of concise standard library methods: map, reduce, stride, etc. You have to learn what they do before you use them. That’s a barrier that you have to overcome before you can start working in the language. The more of those there are, the higher the barrier becomes. As a developer community, we’re best off keeping those barriers as low as possible.

Radek rightly points out that there’s a spectrum, and the more narrowly tailored your use case is, the more appropriate a concise method name might be. But I disagree with the idea that short method names are appropriate in a base class used across your app, or even in framework code. Even methods that get used all the time should be readable. Doing so reduces the amount of time that a new developer has to spend digging through your source code in order to figure out what’s going on. (I shudder to imagine all the command-clicking to figure out what things like funnel or fetch or grab might do.)

I propose that the only real place where very short, concise names make sense is in the language itself. Essentially, this refers to things like map that are already built into Swift. We’ve got autocomplete to help us with the rest, and Swift already reduces some of the extra typing from Objective-C.

Why does this all matter, and why have I been ruminating on it for the past couple of weeks? Because Swift is new, we have a unique opportunity to shape its conventions. I’ve done some Ruby programming in the past, and although it’s a nice language, I don’t want to develop iOS apps in it. I think the iOS and Mac developer communities will do themselves a favor by sticking to longer, more descriptive method names in all but the rarest of circumstances.

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

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.

Web Services, Dependencies, and CloudKit

Brent Simmons blogged a response to my question about dependencies for apps, and he outlined a number of questions developers should consider when choosing a web service:

How long will this service be around? How difficult would it be to move? How much of this service’s unique features do I use? How much benefit do I get from those?

This extends to software, too. What is a given package’s reputation for security? Is it likely to be maintained in the future? Will upgrading to get a security fix also mean revising some of my code?

You have to plan for scale. Will this service and and those software packages allow room for growth? (Sharding, running multiple instances, etc.)

That got me thinking about how CloudKit fits into this picture. As an iOS developer, CloudKit is immensely appealing at first glance. The API is low-level enough that you have a good deal of control over how your app interacts with the server. At the same time, you get a lot of server-side functionality for free, which leaves you with more time to focus on building a great app. But I still have a lot of misgivings about it. I’m going to go through some of Brent’s questions with regard to CloudKit, changing the order a bit here and there when it makes sense.

How long will it be around? Is it likely to be maintained in the future?

I have to say this is an area where I don’t have a lot of confidence in CloudKit. Although Apple’s cloud services have improved somewhat over time, they’ve also gone through a lot of incarnations. Moreover, Apple has a tendency to lose focus on products that aren’t a huge success, and encourages developers to move to the latest and greatest tech. If CloudKit isn’t a big success, I’m not confident that Apple will continue to pour resources into improving it. Past experience leads me to worry that they’d spend more time building a replacement system and promoting it to developers.

What is a given package’s reputation for security?

This is a strong point for Apple. Although CloudKit is a new product, both security and privacy are clearly important to the company. No system is completely secure, but I don’t have any more concerns about security in CloudKit than I would with Azure or any other competing service.

Will this service and and those software packages allow room for growth?

This is a tough question to answer. CloudKit is a fairly opaque box in terms of implementation, so it’s difficult to say how well it would scale. Apple clearly has vast resources at its disposal if it chooses to use them, but the fact remains that developers probably won’t get a whole lot of information about how CloudKit scales. It’ll either scale without us having to do anything, or it won’t. Even the storage and data transfer limits are unclear beyond the free tier. The documentation lists the usage you get for free with each app and additional user, but then simply says, “If you need more capacity than the limits listed above, contact us.” That’s hard to plan for.

How difficult would it be to move?

For me, this is the killer. As it stands now, it seems that it would be incredibly hard to move a CloudKit-based app to another platform. There is simply no obvious way to move data en mass from CloudKit to any other service. Maybe this is possible and Apple just hasn’t discussed it publicly, but as a developer, I need more certainty than that. Maybe CloudKit will work wonderfully for many years to come. But maybe it won’t, or maybe I’ll eventually want to do something that CloudKit doesn’t support. For those and a host of other reasons, I can’t imagine building critical aspects of my app around a service that doesn’t let me have a backup plan.

Brent talks a bit in his post about choosing Azure for Vesper. Of course, CloudKit wasn’t available when they were adding sync to Vesper, but I imagine the decision would have been the same regardless. CloudKit sounds like a great option for some kind of incidental feature, but not for anything central to the app experience.

Tunnels DC Retrospective

A few weeks ago, I decided to pull my Metro app, Tunnels DC, from the App Store. After almost four years in the store, I thought it might be interesting to do a bit of a retrospectve on the app, what worked, what didn’t, and why I eventually removed it from sale.

Tunnels DC debuted on the App Store on November 9, 2010. I’d recently left a job, which gave me the extra hours I needed to finish the project after tinkering with it in my spare time. Back then I was commuting daily on the Metro, and although there were other apps that purported to show train arrival times, few were using Metro’s then-new API. Many of the other apps in the category also lacked much design polish. I felt that there was an opportunity for success with a well-designed app backed by official API data from WMATA itself.

Unfortunately, Tunnels DC was never the commercial success I hoped it would be. Although I certainly didn’t expect to be making a full-time living off the app, I hoped that it would generate better sales than it did. Below are some charts showing the app’s revenue over time.

As you can see, the app’s best year was by far its first. After that, sales tailed off significantly. Even in the first year, the best sales days totaled less than $30. Most days were closer to $1-2. By the end of the app’s life, most days had no sales at all.

I attribute the app’s poor sales to two main factors:

Competition

This is probably the biggest reason the app wasn’t a success. In an increasingly crowded category, there just wasn’t much to set Tunnels DC apart. It wasn’t long before most apps were using the official API. Some supplemented that with additional data that wasn’t publicly available. Others clearly had very strong design teams working on them. Finally, a few apps were backed by large companies that could afford to promote their apps heavily. For example, DC Rider is published by the Washington Post, which is conveniently able to promote the app in their newspapers.

Tunnels DC also faced strong pressure on prices. Many of its competitors were free apps. Some of these had ads, while others were published by companies with other revenue streams. I considered making Tunnels DC free, but decided against it for three reasons:

  1. I wanted the app to pull its own weight. Although Tunnels DC never made a ton of money, it at least covered the annual cost of an iOS Developer Program membership that allowed it to be in the App Store. If the app were free, I’d be paying out of my own pocket to get it out into the world.
  2. I didn’t want to put ads in the app. I hate using apps with ads and would much rather pay a buck or two to get an app without them. Moreover, I wasn’t confident that ads would generate much revenue, even if app downloads increased somewhat.
  3. I guessed that a free app would come with increased support demands. I’ve heard a lot of developers talk about how free apps generate more negative reviews on the App Store, and more email from people demanding new or different features. I figured I’d rather stick to a low-priced paid app, even if it meant fewer downloads.

Limited Market

By its nature, Tunnels DC is only useful if you’re in the Washington, DC metro area. There’s no real reason for someone who lives elsewhere to buy the app. As such, the pool of people who might even consider buying the app is relatively small.

Limited Investment

Given the app’s modest download numbers, I hesitated to put a lot of time into adding features. Realistically, it’s unlikely I would have gotten a very good return on my time investment. If I’m being honest, I also didn’t have a ton of ideas for ways to expand on the concept. In such a highly competitve app market, I needed to come up with a good way to differentiate my app from others. Since I failed to come up with strong new feature ideas, I decided to spend my time elsewhere.

Ultimately, my decision to pull the app from the App store was a result of poor sales numbers. By this summer, downloads had decreased so much that the app didn’t seem worth even the minimal level of support it required. I was also given a push by the start of service on Metro’s new Silver Line. As the Silver Line launch date approached, it was unclear that the API would support it. A tip from someone familiar with the situation confirmed my suspicion that the API is not high on WMATA’s list of priorities. Although the API did eventually gain support for Silver Live trains, the uncertainty surrounding it was enough to tip the scales in favor of removing Tunnels DC from sale. Although I’d almost certainly have done so sooner or later in any event, the issue with data reliability served as a prompt to pull the trigger.

Tunnels DC was never a project designed to pay the bills. Nonetheless, it does offer some lessons for next time. Foremost among these are:

  • Pick a good market. Make sure it’s big enough to support sustained app sales.
  • Have strong features that set your app apart. This seems obvious in retrospect, but I think it’s an easy trap to fall into. The more crowded the category, the more the app needs to differentiate itself from the competition.

I have a couple of app ideas in the works, so there should be an opportunity to put these lessons into practice sooner rather than later. Stay tuned.

Using Third-Party Code in iOS Development

Last weekend at CocoaConf DC, there was one refrain that really caught my attention: be wary third-party code. Avoid CocoaPods. Do things yourself. Speakers said it. Conference attendees said it. It seemed to be everywhere.

I don’t buy it.

Developers on other platforms thrive by making good use of third party, open source code. The Ruby community is a great example. You can find a gem for just about anything. Some are great, some are terrible, and a lot lie somewhere in between. But the existence of all these gems means you don’t have to re-invent the wheel for every new application. You can spend your time focusing on the things that are unique to your app.

Unfortunately, there seems to be a fairly deep cultural difference in the Objective-C community that rejects third-party code.

There are some key differences between writing a web app in Ruby and an iOS app in Objective-C that may account for the do-it-yourself sentiment. Most prominently, web developers have control over the system their app will run on. Servers can be configured with the exact OS and language versions that the app was designed and tested on. If developers keep the OS, language, and gem versions constant, the gems should continue to work correctly. (That said, web developers certainly use things like jQuery that rely on the browser, which changes under them all the time.)

On iOS (or the Mac), developers have much less control over the OS version that their apps run on. Sure, you can set a minimum requirement, but that doesn’t stop things from changing in the future. If Apple makes major changes in iOS 8, it could break third-party code. That lack of control over the complete environment does make third-party code a little more prone to headaches in Objective-C.

So should that dissuade iOS and Mac developers from using third party code? I don’t think so. Changes in the OS could just as easily break code that you wrote yourself, and when that happens, you’re on the hook to fix it yourself. Moreover, good third-party code shouldn’t break in catastrophic ways. Well-designed, well-maintained code should keep up with major OS releases. Apple gives ample time for beta testing before major updates, and rarely removes functionality without warning.

Just as on other platforms, the key to taking advantage of third-party code is to use it carefully and judiciously. Look first to widely-used, actively-maintained libraries. Plan how you use third-party libraries so you could replace them if necessary. Of course, don’t rely on them for everything. There’s always a time to do your own work. The power of sharing code is that you can spend more time on what makes your app unique, and less time reimplementing work others have already done.

The Age of Tim Cook

After all the product announcements and updates in yesterday’s WWDC keynote, Tim Cook closed by showing a new Apple ad titled “Designed By Apple.” Just as in the recent iPhone ads, we see images of people going about their lives. They might be holding an iPhone or sitting near a MacBook, but the gadgets are just barely there, almost a whisper of themselves. The focus is unquestionably on people. The voice-over in Designed by Apple reads as follows:

This is it.
This is what matters.
The experience of a product.
How it will make someone feel.
Will it make life better?
Does it deserve to exist?
We spend a lot of time on a few great things, until every idea we touch enhances each life it touches.
You may rarely look at it, but you’ll always feel it.
This is our signature, and it means everything.

After more than a year at the helm, it’s clear that Tim Cook is putting his stamp on Apple, and this is it. In these commercials, the technology gets out of the way. Products aren’t a goal on their own, they’re a means to an end, a way to make people’s lives better. You can hear that philosophy shine through when Cook talks about things like iOS’s accessibility features that let a blind man to go for a walk in the woods. The focus isn’t on gee whiz technology, it’s on what people are able to do with it. The point of the iPhone camera commercial isn’t the number of megapixels or colors – it’s the photos people take of their friends and loved ones, their parents and their children.

You can also see that theme emerging in iOS 7’s new design. We can quibble over aesthetics, but the goal of getting design out of the way and letting content take over is admirable. Again, the focus isn’t on the technology, but what you do with it. It’s not on how your email client looks and works, but on the messages you get from people in your life.

Of course, Apple is a product company, and its goal is to sell us gizmos and gadgets. But the remarkable focus, and one that’s quickly becoming Cook’s signature, is on doing that by making products that really enrich people’s lives. It’s not about being flashy, or having the most features, or checking off the most boxes. Some will dismiss that as mushy gobbledygook, but it’s not the worst way a company could answer the question, “Should we build this?”

This isn’t about leaving Steve Jobs behind. Far from it. Under Steve, Apple’s goal was always to make great products regardless of what others were doing. But make no mistake, Tim Cook is putting his own stamp on Apple. It’s a little more human, a little more personal, even down to the funnier, more casual tone of the WWDC keynote. Cook has chosen to surround himself with people and a philosophy that focus on the humanity in technology even more directly than Steve did. Sounds like a pretty good sign for the months and years ahead.