Send a Type to Obedience School – Using Swift Extensions for Additional Protocol Conformance

Did you know that you can make any Type (here meaning Class, Enumeration, or Struct), even already-existing ones that you don’t have the source code for, adopt a protocol that it doesn’t normally conform to out of the box?

You caneven if you don’t have the original source code for that Type! It’s a powerful and intriguing proposition. Let’s explore how this is possible.

How, you ask?

Well, as the title of this article suggests, Swift extensions are the way to do it. To demonstrate this capability, consider the following scenario:

  • You’re using a library that lets you create instances of Bird , and you don’t have access to the source code for the library.
  • Bird has a property called species and a property called commonName .
  • You’d like Bird to conform to the Printable protocol, defined in the Swift standard library, so that you can call println(_:) on Bird instances, and have it log something useful to the console.
  • When println(_:) is passed a Bird instance, you’d like it to print out something like “[species] (ie, [commonName]).”, and have [species] and [commonName] be replaced by the Bird‘s real values.

Remember that you don’t have access to the original source code of Bird . Without Swift extensions, there would be no way for you to tell the compiler that you’d like Bird to adopt and conform to the Printable protocol.

Thankfully, extensions do exist, and we can teach a Bird new tricks, enabling its conformance to Printable .

Protocol Conformance Extension

As stated in the Printable protocol documentation, a Type adopting the Printable protocol must implement a single, read-only property named description .

The extension, then would be implemented as follows:

1// Explicitly specify protocol adoption
2extension Bird: Printable {
3
4    // Implement the required property to make Bird conform to the protocol
5    var description: String {
6        return "\(species) (ie, \(commonName))"
7    }
8}

The magic line in the code above is highlighted. This tells the compiler that Bird will be extended to adopt the Printable protocol.

Of course, the remaining requirement then, is to implement the specification of the protocol so that Bird conforms to it, which is what the body of the extension contains.

Note that simply extending Bird to have a read-only description property will *not suffice for making the Type adopt the protocol. There is no “implicit” protocol adoption in Swift, so you must specify in the extension declaration that you intend for the Type to adopt the protocol.

Conclusion

With this little example, you’ve seen how using an extension can enable a Class, Enumeration, or Struct to adopt and conform to a protocol that it normally wouldn’t out of the box. It’s especially neat that you can do this for any such Type, whether you have control over its original source code or not.

comments powered by Disqus