The RawRepresentable protocol
What is it and how to make use of it?
If you’ve ever used a Swift enum with a raw value, you may not even realise that you have already worked with the RawRepresentable
protocol. But what is it and how can you make use of it?
In this article we are going to investigate the RawRepresentable protocol and I’m going to show you some neat ways for using the protocol to our advantage.
Why are we talking about this?
The other day I’ve open sourced a really small package, SecureStore. Basically it’s just a keychain access wrapper for swift that is using the Security
framework from apple to read and write the keychain.
One of the convenience features of the package is that you can use any enum with a String
raw value as a key for saving or retrieving values from the store like this:
let value = store.retrieve(for: MyEnum.myKey)
The advantages of this may be pretty clear but let’s break them down real quick:
- The author of a package may not be able to provide an enum that describes all cases that the user needs. (Like my case with the secure store. You may have any string as a key)
- Using an enum prevents bugs like a typo in your string
- Of course, a string property on the type using the store can work just as well and there is really nothing wrong with that solution either, I just find it more convenient in many cases to have an enum with all the possible keys
So what about the RawRepresentable protocol?
As the documentation states, RawRepresentable<T>
requires the conforming types to be able to convert to and from a raw value of the type T
. This means that a type conforming to it will have a property called rawValue
and an initialiser with a parameter rawValue
of type T
. Does that sound familiar?
Exactly, that’s just like an enum with a raw value and guess what.. an enum with a raw value does conform to the raw representable protocol.
Realising this, let’s see how to implement a function that takes any enum case as an argument:
func printRaw(_ value: any RawRepresentable<String>) {
print(“The value is \(value.rawValue)”)
}
And that’s it! Let’s test it
enum TestEnum: String {
case testCase = “testCase”
}
printRaw(TestEnum.testCase)
As you may have guessed already, the output of the call will be The value is testCase
.
But it is generic for a reason!
You are not limited to using strings here as the generic parameter of the protocol. It's just happens to be my most recent usecase. Any type of data your function needs, you can represent it as an enum case thus making a custom namespace for your parameters!
Conclusion
As you can see, this is not one of those world changing discoveries, but rather a small bit of spark to make your APIs a bit nicer to use. If you want to see this in action, or just need a simple way of working with keychain, feel free to check out SecureStore and if you have any questions about this or any other topics, reach out to me on X
Related articles
Here are some more articles that may interest you. Check them out!
Proportional layout with SwiftUI
published on January 25, 2025
SwiftUISwiftStarting from iOS 16, SwiftUI gives us the option to build custom layouts that can control very precisely where each subview should be placed. We have the option to build layouts that can be used just as the VStack, HStack or any other built in Layout you may be familiar with from SwiftUI.
Read moreThe @ and # symbols in Swift
published on January 2, 2025
SwiftWhen a new feature is introduced in a programming language, we as developers are often quick to assume it will solve many of their challenges. The excitement to experiment with such features is natural, but it’s often accompanied by the realisation that every solution brings its own set of unique challenges. This was no different when actors were introduced.
Read moreThe reentrancy problem
published on December 16, 2024
SwiftConcurrencyWhen a new feature is introduced in a programming language, we as developers are often quick to assume it will solve many of their challenges. The excitement to experiment with such features is natural, but it’s often accompanied by the realisation that every solution brings its own set of unique challenges. This was no different when actors were introduced.
Read more