They say good programmer writes 100 lines of code per day but a great one deletes 50. Do you agree? Let’s become the latter by following the Don’t Repeat Yourself principle, because best code is no code at all 😉

Repeat features, not code

It’s a common scenario in software development to put a similar functionality in multiple places of the project. Most iOS applications consists of a few screens, each a separate UIViewController . Now, imagine your product owner comes and says:

We must inform user about API errors! Let’s just present an alert when request isn’t successful.

That’s easy! All you need is a small function in your view controller:

Now your LoginViewController knows how to display an error alert. But hey, login isn’t the only place your app makes API requests, right? Taking our latest product — RocketLuncher — as an example there’s also a registration screen, menu, order summary, change password and so on. Each requires error handling. Pasting the same method in all these classes causes your codebase to grow and violates the sacred DRY principle. Also, future changes are troublesome because you must apply them in multiple places.

How to avoid code duplication?

First thing that might come to your mind is to add an extension to UIViewController class:

Pros: it’s easy and the function is instantly available in all your view controllers. Cons? Well, the function is available in all your view controllers, even ones that don’t need it. It’s always better to have control over your code’s access scope.

What about subclassing?

Since we want presentError function to be available only in certain classes, lets follow Object Oriented Programming (OOP) paradigm and create UIViewController subclass. We can use it wherever we want to present errors:

That’s better! Not only we got rid of code duplications but also our function is available only where we explicitly choose to. However, there’s a big problem with this solution. Imagine you’d like some screens to also show UIActivityIndicator . Following the same path you create ActivityIndicatorViewController with presentIndicator function. Swift doesn’t support multiple inheritance, so you can’t create a class that’s both ErrorPresentingViewController and ActivityIndicatorViewController subclass. We could add new ErrorPresentingAndActivityIndicatorViewController but this even sounds horrible 😤 Clearly, we’ve reached OOP limits. What now?

Let’s use protocols!

According to an amazing WWDC 2015 talk by Dave Abrahams, Swift is a Protocol Oriented Programming (POP) language. Let’s look into Swift documentation to find out about protocols:

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol.

How can we use it to solve our problem? First, let’s declare a protocol:

Following the definition, usually we would adapt it by a class, struct or enum and provide implementation there. This however doesn’t solve our code duplication problem. Instead, we’ll use protocol extensions:

Protocols can be extended to provide method and property implementations to conforming types. This allows you to define behavior on protocols themselves, rather than in each type’s individual conformance or in a global function.

That’s exactly what we need. Let’s code!

By creating an extension on ErrorPresenting protocol, all conforming types automatically gain presentError method implementation without any additional modification. Notice line 5: where Self: UIViewController . When you define a protocol extension, you can specify constraints that conforming types must satisfy before the methods and properties of the extension are available. In this case we want to present an alert so we need a present function which is available in UIViewController .

All that’s left to do is make each view controller requiring error handling conform to ErrorPresenting :

Now you can use presentError in all and only those view controllers that conform to the protocol — you have full control over who can access your method. There’s also no code duplication: presentError is implemented only once in a protocol extension. Congratulations, you’ve just learned how to write less code ☺️

EDIT:

Read the follow up to the article, To err is human but how to show it?, about convenient way of displaying errors in iOS apps.

Don’t forget to tap and hold 👏 and to follow DaftMobile Blog (just press “Follow” button below 😅)! You can also find us on Facebook and Twitter 🙂