Type Erasure in Swift
Get rid of that type information
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.
- You will be expected to be aware how to make a Single View Application, or a Playground to run Swift code
- You will need to know about protocols in Swift
- The heart of this article is a constant (and annoying) talk about generics
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.
In that instance, my
HTTPManager conforms to a
HTTPManagerProtocol which can then be represented as a stored property, for example in my
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
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).
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.
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.
This is now our main class for the HTTPManager
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!
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