Type Erasure in Swift

Get rid of that type information

Image for post
Image for post
Photo by Mark Harpur on Unsplash

Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 11.4.1, and Swift 5.2.2

This article is example laden, and shows how I’ve used Type Erasure in my production Apps. It should help if you wish to know what Type Erasure is and how you might apply it in your Swift code.

Prerequisites:

Terminology:

Type Erasure: Removing type information

When programming in Swift we have a type-safe language, that is Swift is strongly typed.

Now sometimes you might want to use type erasure, that is removing type information to find out why you might want to lose information in this way we have to think about protocol-oriented programming and specific implementations of the same…

Protocol-oriented programming — A real life need for Type Erasure

When we code against an interface (in Swift we code against a protocol) we develop a contract between the client and supplier of a service.

I’ve previously used associated types to create articles on Operation queues where I’ve a protocol with an associated type to make the protocol in some sense generic.

In that instance, my HTTPManager conforms to a HTTPManagerProtocol which can then be represented as a stored property, for example in my UserListRetrievalOperation class:

where, inevitably the class must itself be generic with <T: HTTPManagerProtocol> being added to the class signature. The reason for this is that we need to save an instance of type T, and that means we need to be able to specify what type that property will be. The danger with this approach is that we are looking down the barrel of making everything generic. If you want to take a look at this approach in situ please do take a look at the full article , where generic protocols have been used to allow full testing of the classes that have been used.

Now this approach isn’t a problem per se (it met it’s goals, and delivered a rather spiffing article), but we can do better. You don’t need to guess: A better approach is using Type Erasure.

The approach in the article

This particular article is about Type Erasure, and therefore I’m repurposing my favourite basic network manager to simply make a network request.

A little respect The approach I’d usually take is MVVM-C or similar, perhaps making network requests from the coordinator. However, for this article I’m attempting to make everything as simple as possible — and we will make network requests from right in the UIViewController. The reason for this is that making this a discrete article, away from architecture should make Type Erasure easier to understand without the use of any particular archiecture (for those interested, this is trivial to implement in other architectures).

The example

I’ve gone for an approach not using the storyboard so I can inject the network manager using the same mechanism for testing and production code.

So we can pass through this step-by-step (although please do download the code from the repo, that’s what it is there for!) Initialise the VC

You see the problem — that ViewController<HTTPManager<URLSession>>(network: network) makes me feel a little sick.

The view controller can be generic, and store the network manager

but uggh. We have to continue to drag the associated type around with us, and this will continue up until it pollutes the AppDelegate and/or scene delegate.

AnyHTTPManager

We are going to use a type erasure technique commonly used in the Swift standard libarary — SwiftUI in particular has the AnyPublisher type that most who have touched SwiftUI have become familiar with.

We say that we wrap a protocol (which has an associated value) into a generic type, which can then be used without making each hosting object generic.

The key:

This is now our main class for the HTTPManager

In the SceneDelegate in the example I've instantiated the HTTPManager and then injected this into the view controller (I'd usually put this into the ViewModel, but this example is meant to be easy and it is certainly not production-ready).

I’ve then created an Initializer in the View Controller that lets us store the HTTPManager - as an AnyHTTPManager with associated type

which means that then we can make network calls from within any particular function in (this case) the view controller

Look — there’s a nice repo that enables you to see all of the code that is avaliable.

In any case, Type Erasure is Cool!

Conclusion

It seems surprising that losing information is actually useful — but that is exactly what the type erasure is.

That is, it erases the type.

Does that make it easier to understand what AnyPublisher is in Swift? Tell me.

In any case, have a nice day.

If you’ve any questions, comments or suggestions please hit me up on Twitter

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