Protocols with Associated Types in Swift

Protocols are important

Image for post
Image for post
Photo by S O C I A L . C U T on Unsplash

Associated Types in Protocols make those Protocols more powerful than you might possibly imagine. How? Read on to find out!

Prerequisites:

  • Understand the use of protocols in Swift (guide HERE)

Terminology

Associated type: A placeholder for an unknown concrete type (at build time)

Protocol: A blueprint on methods, properties and requirements to suit a piece of functionality

Using associated types

Associated types make protocols generic, and using Swift we can later specialize the protocol. The syntax is different from plain generics in Swift but don’t worry, I’ll take you through this in this article.

To put it another way, a protocol is simply an abstract set of requirements that are implemented by a concrete type. So associated types are a way of naming things that are within these requirements, and expand the definition without defining will conform to the protocol. Therefore associated types allow us to make generic protocols which are only specialized later by the conforming concrete types.

Associated Type Examples

Associated Types can be used to show how we can conform to a protocol, essentially making a protocol generic.

Let us see an example. Here we are going to use collection types to show how we can make types conform to the protocol.

Protocols can be specialized with constraints, or by making concrete types conform to the protocol.

Creating a protocol for a set type

Here I’ve created a protocol that sets can conform to. Now I know that Swift’s Set type can be used to achieve this but the purpose of this demonstration is NOT to recreate the Set Type but rather to show how Protocols can be used with associated types.

With that side, let us go ahead with creating the protocol

protocol SetType {
associatedtype Element
func insert(_ element: Element)
func contains(_ element: Element) -> Bool
}

So each set type needs to have a function to insert elements into the set, and a function that confirms if an item is contained in the set.

Now what is important here is the Element as an associated type. We don’t know much about Element as specified in this protocol, but that’s what makes the protocol generic (which is exactly what we want).

Creating a set that contains Integers

SetIntegers as below will allow us to offer the functions detailed above.

class SetIntegers: SetType {
var set = Set<Int>()
func insert(_ num: Int) {
set.insert(num)
}
func contains(_ num: Int) -> Bool {
return false
}
}

We can then create a SetIntegers instance as below

let mySet = SetIntegers()
mySet.insert(4)

Now it is clear that mySet conforms to the protocol , and it is equally self-evident that mySet is storing Integers.

Creating a set that contains Integers

In a similar way to SetIntegers, SetString can be defined.

Of course, once again the class conforms to the protocol

class SetString: SetType {
var set = Set<String>()
func insert(_ string: String) {
set.insert(string)
}
func contains(_ string: String) -> Bool {
return false
}
}
let strSet = SetString()
strSet.insert("Data content")

Remember

Protocol extensions allow us to provide default implementations — this makes it possible to simplify the protocol and classes above and create an even better and tidier solution.

Never, never forget.

The error messages associated with associated types

There is an all too common error message when using protocols.

protocol can only be used as a generic constraint because it has self or associated type.

The cause of this error for protocols is that we need to understand that it is a generic constraint so we need to tell the compiler which type is being used.

I found this when creating the post for mocking URLSession. That is we need to give it the generic type. Specifically constraining the parameter with <T: URLSessionProtocol>

Conclusion:

Protocols with associated types are powerful — and are a great way to make protocols generic, reusable and even more powerful!

What a great tool to add to your Swift toolbox.

Extend your knowledge

  • Apple have some nice documentation around protocols (Guide HERE)

The Twitter contact:

Any questions? You can get in touch with me here

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store