';

Subscribe to The Swift Post

Enter your email address to subscribe to The Swift Post and receive notifications of new posts by email.

Swift 4’s Codable

It is almost certain that at some point in your app development journey, you needed to (or you will soon :]) serialize some object or value and parse JSON response to your model. If I am right, then this might worth your time.
In Swift, we used to use NSCoding protocol to serialize our objects. To conform to NSCoding we very often ended up making our classes inherit from NSObject and then after some cha cha and samba and some freakishly long amount of time, we finally manage to implement the expected init(coder:) and encode(with:) methods. But what about structs right? Well, most people found the solution in introducing third party frameworks to their projects. Hopefully, the fight for serialization and mapping has come to an end.

What now?

Swift 4 introduces a protocol called Codable which is a composition of two other protocols: Encodable & Decodable. Codable allows us to serialize and deserialize classes, structs and enums with almost no effort. Most types including String, Int, Array, Dictionary are conforming to this protocol. So when we create a new type containing properties which already conform to Codable, we do not need to write one more line of code. The Person type below conforms to Codable just like that:

Serializing Person to JSON:

Voilà, person value converted to data just like that.

Now let’s deserialize:

What’s in it for me?

There are two awesome things that I found Codable useful for:

  1. Mapping
  2. Archival & Unarchival

Mapping

Say you receive your responses as a JSON string (even better if it comes as encoded data). It would be delicious to initialize our types with that JSON string, right? Let’s write it down:

Thanks to powerful protocol extensions, once again, we need not to do anything further with our types (multiline strings with triple quotation marks below, are also introduced in Swift 4).

A little bit of refactoring to Person:

Adding optionality to Mappable initializer is needed to avoid possible failures due to missing fields in the response. And when we make a property optional (friends in this case), Codable will still work if the optional field is not included in the data.
If you were using some third party framework like ObjectMapper for this, great news, you no longer need to. Not only it already offers the same functionality for mapping, it also saves you from finding the values with the keys by subscript. It infers the keys from the property name. Swift 4 also provides the CodingKey protocol to grant you the freedom of naming your properties as you like:

I have changed name to alias and friends to comrades because I can.

Archival & Unarchival

NSKeyedArchiver & NSKeyedUnarchiver also supports Codable. Here is how we archive a value:
NSKeyedArchiver.archiveRootObject(person, toFile: "file")
Along with your classes that conform to NSCoding, now all your types that conform to Codable can be handled by NSKeyedArchiver.
Unarchival, here you go:
guard let data = NSKeyedUnarchiver.unarchiveObject(withFile: "file") as? Data else {   return }
If you chose to encode your value with JSONEncoder and then archive it, you can decode it with JSONDecoder after unarchival.
This feature allows us to persistently store our Codable types.

Final Notes

As you know, Swift 4 is still being developed. For instance, you cannot conform to Codable in an extension (this will be fixed until first release of course). Apart from that, I have not faced with any other problem. If you decide to move forward to Swift 4 though, you can certainly use all these great features. Cheers!

Alp Avanoğlu