Initializing Enums With Optionals in Swift

Ethan Schatzline
2 min readJun 2, 2017

--

For several of the projects I’ve worked on, we’ve used third party code generation libraries for server models and a lot of times, the properties on those server models have been optional. Every time you want to initialize an enum with that optional, you have to first unwrap it before passing it in as a rawValue.

Every time was the key part there. Sounds like duplicated code. We can easily reuse this code by making an extension. You can only initialize an enum with a rawValue if the enum conforms to RawRepresentable.

A simple example of this would be:

enum Planet: String {
case mercury
case venus
case earth
case mars
case jupiter
case saturn
case uranus
case neptune
}

String is a RawRepesentable, so you can do let earth = Planet(rawValue: "earth") and it will initialize a Planet as .earth.

Optional RawValues

init?(rawValue: RawValue) is the initializer for an enum that conforms to RawRepresentable. The rawValue parameter must not be optional. To avoid unwrapping our optional rawValue each time before initializing, we are going to create an extension that allows us to pass in an optional RawValue.

We do this by extending RawRepresentable and creating a new init function. This one is also failable, but the RawValue parameter is optional. Here’s what we get:

extension RawRepresentable {    init?(optionalValue: RawValue?) {
guard let value = optionalValue else { return nil }
self.init(rawValue: value)
}
}

So now if we get passed an optional string from the server like this: var planetString: String? = "earth" even though planetString is optional, and in this case not nil, we can still do let planet = Planet(optionalValue: planetString) and we have the same object as before, without having to unwrap planetString.

As always, feel free to comment with any feedback, suggestions, remarks, or criticism. I would love to hear what you think!

Thanks for reading,

Ethan

--

--