NEW: Master Swift design patterns with my latest book! >>

< Previous: Protocol-oriented programming for beginners   Next: Wrap up >

Extensions for brevity

Like I said earlier, it's extremely common for developers to use extensions to add functionality to things. In some ways, extensions are similar to subclasses, because we could easily subclass UIView and add new methods to it like this:

func fadeOut(duration: TimeInterval) {
    UIView.animate(withDuration: duration) { [unowned self] in
        self.alpha = 0
    }
}

So why use extensions at all? The main reason is extensibility: extensions work across all data types, and they don't conflict when you have more than one. That is, we could make a UIView subclass that adds fadeOut(), but what if we find some open source code that contains a spinAround() method? We would have to copy and paste it in to our subclass, or perhaps even subclass again.

With extensions you can have ten different pieces of functionality in ten different files – they can all modify UIView directly, and you don't need to subclass anything. A common naming scheme for naming your extension files is Type+Modifier.swift, for example String+RandomLetter.swift.

If you find yourself wanting to make views fade out often, an extension is perfect for you. If you find yourself trimming whitespace off strings frequently, you'll probably get tired of using this monstrosity:

str = str.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

…so why not just make an extension like this:

extension String {
    mutating func trim() {
        self = trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }
}

You can extend as much as you want, although it's good practice to keep differing functionality separated into individual files. That said, "good practice" and "I'm up against a deadline" are rarely the same, so expect to see extensions named String+Additions.swift that add a collection of unrelated things to the String struct.

One tip: when you’re making your extensions, try to think about whether it makes more sense for your code to be a method or a property. For example, the trim() code above is probably a good fit for a method, but you could also make it a computed property if you prefer, like this:

extension String {
    var trimmed: String {
        return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }
}

Very roughly, things that make sense as methods should be verbs, like trim() or trimmed(). Things that describe state – even when that state is calculated – should be properties, e.g. UIColor.blue.

If you want to see what super-charging Swift's built-in data types can look like, look up the ExSwift extension catalog on GitHub at https://github.com/pNre/ExSwift.

Learn Server-Side Swift now!

Take your Swift code to the server and become a full-stack developer with my latest book: Server-Side Swift!

< Previous: Protocol-oriented programming for beginners   Next: Wrap up >
Click here to visit the Hacking with Swift store >>