Headers are Dead. Long Live Protocols.

Patrick Smith
3 min readOct 13, 2015

--

In my days of writing Objective-C classes, I often turned to the .h header file to do my thinking. It allowed me to focus on the key parts of my API, without worrying too much about its implementation.

I could declare public properties, using the @property syntax. All I had to decide on was a name and a type. I could try and work out the best names, which noun would best suit this? Is a shorter name or a longer name more descriptive? What’s the most obvious name for this? What do Apple’s frameworks use in situations like this?

I could declare the methods that a caller would use, and work out the best verbs to use — fetch, load, retrieve, use, calculate, resolve — again looking at Apple’s APIs for guidance. I would go into a documentation viewer and type the first word or two and see what already had been used. If nothing matched, I would try a different word until one did. Occasionally I would disagree with what Apple had chosen, but not often.

If the words I was using weren’t something that appeared to be in existing frameworks, I would turn to the thesaurus to find and compare synonyms. Writing code is about writing for people, not for computers. I want to use the best words I can to express the pieces of my program. Clarity is the most important thing to measure by, not terseness.

I want to use english words that relate to existing concepts where possible — words from the business world, the creative world, or the literary world. I want to steal terms, concepts, and even systems and make them my own. Without going overboard, the more meaning I can bring to my code, the less it reads like a ‘code’ and the more it becomes an expression of information and concepts.

With the removal of the .h file, Swift initially seemed to have removed this process for me. No longer am I in two stages of working: the declarative stage, and the implementation stage. They are tied together in the one file.

I can try writing a class by pure declaration, but Swift’s aggressive compiler can often make this a pain. Functions with an expected return type will error if there is no implementation yet. The smart indentation of Xcode will often stop working once there is a preceding error.

However, Swift brings tools to allow a declarative approach to API design.

First, are protocols. Apple at 2015’s WWDC presented Protocol-Oriented Programming in Swift, which encouraged the use of protocols to abstract and decouple code. The great thing about protocols is that they are purely declarative. You only focus on the public API, which a struct or class will implement later.

So the .h writing stage of a module, such as a class, can now be replaced by the protocol writing stage. What is this piece focused on? What is its scope? What are the concepts involved? Maybe things could be broken into several protocols? Get the pieces of your program as focused as possible.

A more focused public API will often allow a more focused and straight forward implementation to blossom.

Also handy in the declarative stage are enums. These allow you to very simply declare the basic choices that inhabit your app. State the enum’s cases, and leave their more complex logic to extensions. Do the same for structs, or even use a ‘dumb’ tuple instead.

The declarative nature of Objective-C headers allowed a programmer to focus on just the API and not its implementation — a workflow’s separation of concerns. Protocols bring the same benefits to Swift, whilst providing greater opportunities for abstraction and decoupling from the eventual implementation.

--

--

Patrick Smith

@concreteniche · Product designer for the web & Mac. Loves experimenting with React, Swift, and UX tools.