RawRepresentable and associated values

RawRepresentable is a protocol in Swift standard library and enables converting from a custom type to raw value type and back. In this post we’ll be looking into how to implement RawRepresentable for enumeration containing an associated value.

Conforming to RawRepresentable

Implementing RawRepresentable requires three steps: firstly, choose RawValue type; secondly, implement initialiser where RawValue type is matched to one of the cases in the enumeration, and thirdly, rawValue getter where enumeration cases are converted into RawValue type.

In the example we’ll be looking into enumeration representing scenes: home, levelSelection and level(Int), where the associated value stores a number of the level. RawValue type is String and without associated values it is quite straight-forward: use switch-case for conversions. When associated values are in the mix, a little bit more processing is needed. Let’s look into level(Int). In the getter returning String we can just compose a string “level” followed by the level number. In the initialiser the string must be matched to that format. First we check if the string starts with prefix “level” (anchored == prefix) and after that try to create an integer from the rest of the string: nice and concise.

enum Scene {
case home
case level(Int)
case levelSelection
extension Scene: RawRepresentable {
typealias RawValue = String
init?(rawValue: String) {
switch rawValue {
case "home":
self = .home
case "levelSelection":
self = .levelSelection
guard let range = rawValue.range(of: "level", options: .anchored) else { return nil }
guard let number = Int(rawValue.suffix(from: range.upperBound)) else { return nil }
self = .level(number)
var rawValue: String {
switch self {
case .home:
return "home"
case .levelSelection:
return "levelSelection"
case .level(let number):
return "level\(number)"
// Examples:
// Scene.home
let home = Scene(rawValue: "home")
// Scene.level(1)
let level1 = Scene(rawValue: "level1")
let paddedLevel1 = Scene(rawValue: "level001")

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s