Swift protocol extensions 101

If you haven’t heard about Protocol Oriented Programming in Swift, you have been living under a rock for the last two months.

Protocol extensions in particular, which are at the core of whole concept, are neat and abstract and complex, and my brain hurts a little when I think about it. But the thing is, it is not that difficult to wrap your head around them.

Consider a protocol:

protocol Behaviour {
    func methodA()
    func methodB()
}

Now, we have two classes that implement that protocol:

class ClassA: Behaviour {
    init() {
        print("classA initializer")
    }
}

class ClassB: Behaviour {
    init() {
        print("classB initializer")
    }
}

But we want them to implement it with a little twist. We want ClassB’s implementation of method B to be a little bit different.

So we can start with a default implementation of the protocol, in a protocol extension:

extension Behaviour {
    func methodA() {
        print("methodA in default extension")
    }
    
    func methodB() {
        print("methodB in default extension")
    }
}

And now an extension to that protocol that will only be aplicable to instances of ClassB

extension Behaviour where Self: ClassB {
    func methodB() {
        print("methodB in specific to class B extension")
    }
}

And if we do this:

let a: Behaviour = ClassA()        
let b: Behaviour = ClassB()
        
a.methodA()
a.methodB()
        
b.methodA()
b.methodB()

We get this trace:

classA initializer
classB initializer
methodA in default extension
methodB in default extension
methodA in default extension
methodB in specific to class B extension

Boom.

Final words

Now, consider the second extension, the one I called ExtensionToClassB. What if, instead of applying that extension to a class type, I apply it to another protocol?

Mind blown.

rfFWukr

One Reply to “Swift protocol extensions 101”

Leave a Reply

Your email address will not be published. Required fields are marked *