Getting the raw values of an enum

I love Swift, and one of the things I love most about Swift are it's enums. While I have a few issues with Swift's enums (mainly they break the editor way too often), I love and use them all over the place.

The problem

Right now I am working on a project that involves a registration form, and we have opted to use a few UIPickerViews in this particular section. To make our lives easier we are using enums to keep track of the selections the user make. The rawValues for these enums are Strings, and I needed an easy way to get those strings to be able to place them into the pickers.

Here's the enum I'll be using as an example:

enum CreditCards: String {
    case AmericanExpress = "American Express"
    case Discover
    case MasterCard
    case Visa
}

The first thing I thought to do was to make a static list of all of the raw values for each of the enums to be used, that looked like this for that example above:

let creditCardRawValues = ["American Express", "Discover", "MasterCard", "Visa"]

But then I thought why not place the raw values right in the enum? So I did just that:

extension CreditCards {
    static let rawValues: [String] = ["American Express", "Discover", "MasterCard", "Visa]
}

That’s not enough for me though. On the project I am working on right now, I am using several pickers, and I needed the rawValues from several different enums. Sure I could explicitly write out all of the raw values for each enum, but that didn’t seem very fluid. What if I could figure out a way to define the rawValues property in one place and have it propagate to each of the enums that I wanted the raw values for? That would definitely be ideal. So I got right on that.

The solution

I made a protocol that required each enum that adheres to this protocol to define an array that contains all of it’s values (in whatever order you desire).

protocol Values {
    static var values: [Self] { get }
}

I realize this is very much like what I have above, where each enum declares its own rawValues property, but this is slightly different. Instead of just having an array of the rawValues, you also get an array of all the possible cases of an enum, which can be pretty useful sometimes.

It should also be mentioned that by using an array of the values of an enum, either changing the name of a case or removing a case will not allow the project to build until you fix that array. Adding a case will sadly not cause such a build error to occur, but that is the only caveat I have run into.

Right after declaring my protocol, I extended it to add a variable called rawValues that, you guessed it, returns all of the raw values of every case declared in values.

extension Values where Self: RawRepresentable {
    static var rawValues: [Self.RawValue] {
        var rawValues: [Self.RawValue] = []
        for value in values {
            rawValues.append(value.rawValue)
        }
        return rawValues
    }
}

This extension is only declared once and is automatically added to every enum that adheres to the Values protocol. It is only added to enums because this extension only extends Values where Self adheres to the RawRepresentable protocol.

This means that now, anytime I want to access a list of the values of an enum, bam, they're all there. And when I want to access a list of the raw values, bam, they're all there too. And this all takes minimal effort.

The future

This solution is a bit wonky, as it relies on developer to make sure that each enum follows the protocol, and also demands that the developer maintain a listing of all the cases in the values list for each enum. However, this is the best solution that I could come up with to fix this problem. The only way this could get better is if Apple adds in a way to enumerate over an enum to get all of the cases of that enum. Until that day comes, however, I'm going to stick with this method.

The playground

I made a little playground to demonstrate the usefulness of this protocol, which you can find here.

Read “Introducing Findmoji” next

Nathan Ansel

Nathan Ansel

Nathan is an iOS Developer that has a passion for making beautiful, well developed apps. He loves Swift, fitness, and playing video games. He can be found on twitter at nathan3o4.