The magic of RawRepresentable in Swift
Extensions I keep coming back to.
Enums are great. In many languages enums arise when we don’t have a binary (boolean) option, but rather one of many. In Swift they simplify even binary events by letting you make otherwise optional variables as non-optional.
But one of the coolest parts about enums in Swift is that they can be of a raw type like a String
or an Int
. Here are a couple of usage cases and extensions for working with such RawRepresentable
enums.
Convert one enum into another
Sometimes you will need to convert one enum into another. For example, you may have a UserType
enum in the data layer of your app:
Notice that we inherited from String
, such that this is enum conforms to RawRepresentable
. The associated type RawType
is String
.
In another part of the app, you may have a log in type that occurs during registration, for example LoginType
:
Now: how to convert from one into the other? You could write out the mapping manually using a switch statement, but a cleaner approach is the following extension:
For the enum, we are converting it into it’s rawValue
(i.e. String
), and creating a new enum from that. For example:
How neat is that?
You can similarly convert a whole array of enums with the following extension:
which returns all the converted enums that it can.
Convert array of raw types to enums
Let’s say you have an array of strings, where each string is one of the cases from the previous example:
To convert it to enums, use this handy extension:
https://gist.github.com/smrfeld/c0780168c5cf819f200973f6f211dd57
Which can be used like this:
You may think “Oooh big deal, I can do that just by calling the enum constructor with rawValue”, but the neat thing here is that the extension infers the enum type, so this works too:
Better optional constructors for enums
You can already construct an enum from it’s rawType
using the provided constructor, which returns an optional type in case the string (or whatever) cannot be converted into the enum:
Those can be improved — what if you have an optional string? Or how about, just any optional thing at all? Let’s create two much more generic constructors:
Now you can construct your enums from any type:
Happy enumeration!