Update: Serialising enums and structs in Swift 4

So, now Swift 4 is here and things are changing. One of the big improvements of Swift 4 is the incorporation of serialisation for classes, structs and enums. In contrast to the previous versions which rely on the old NSObject/NSCoding mechanisms the new Codable protocol is not restricted to classes only. And even better, if you do not have special needs the compiler will synthesise the needed functions for you as we will see later.

There are some nice articles (e.g. by Todd Olsen or Craig Grummitt) which show how to use the new protocols and how to migrate from the old world. I want to update my old ideas for enums with associated values concerning serialisation. So, let’s start over again.

Bad news first: the compiler does not synthesise the functions needed to conform to the Codable protocol for you in the case of enums. So, we have to make them by ourself. Let’s start with the encoding part. The function encode works quite similar to that of the the old NSCoding protocol. It’s called with an encoder and you have to supply the encoded properties of your class, struct or enum. But now it may throw exceptions if the encoding fails.

We are free how we want to map our enum to a codable structure. I prefer to map the cases of the enum to Ints. In our example this is the variable „happiness“. In addition I encode each possibly present associated value separately (in this example „grade“ for Happiness.Happy). In the above mentioned article each case is encoded uniquely with all its associated values at once. If you have several associated values of diverting types you have to introduce a Codable struct to encode them, for me another unwanted layer of complexity. So, here the associated values are encoded in each case separately and in the end I do it for the main value of the enum. Quite simple, isn’t it?

In contrast to the old NSCoding protocol we cannot encode our values directly with the encoder. We need to get an (empty) container first. The keys for the coding are not simple strings anymore as they were in the old NSCoding protocol but String (or optionally Int) enums conforming to the CodingKey protocol. That enum I have defined private in lines  9 to 12.

Well, now to the decoding part. That is performed in the exceptions throwing init. Its quite the other way round to the encoding part. First I get the filled container from the decoder and then I decode each value separately. I just have to take care if the decoding fails. For that I have introduced the error CodingError. That’s it. Now we can test our Codable enum:

Funny enough we cannot give our enum to an NSKeyedArchiver directly; that crashes. Instead we can use the PropertyListEncoder and PropertyListDecoder classes for encoding and decoding the Data object. That we can give to the old class functions:

And now come the good news: To make our struct from this post being Codable we have to do almost nothing:

Here is the complete playground of this exercise:

Enums4.playground

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.