Swift 4 Codable: tips and tricks

Many of you may agree with me when I say the Codable protocol is the best Swift 4 feature, here are some of my impressions about it.

What is it?

If you take a look into the Codable definition you’ll find out that it’s just a way to tell that something is Decodable and Encodable.

Making your custom types conform these protocols will allow you to represent them in different forms such as JSON or property list.

Some of you may know NSCodingthat does something very similar, the difference is that encoding something with NSCoding will produce a Data (NSData) that is basically a buffer of bytes.

Why is it a game changer?

Today every App is connected with web services and most of them provide data using the JSON format for its ease of reading and generating for both humans and machines.

In order to manage JSON data, the client has to “translate” it in objects that can be easily manipulated (eg: structs or classes); this process is called “parsing” and the part of the app that does the job is the parser.

By implementing the Codable protocol in your data model you can forget about parses because your objects will be automatically translated from (and to) JSON.

Let’s see it in action.

Suppose we want to know some basic information about this post and the Medium API give us something like this:

Then our model will probably look like this

The only thing to do now is make our Post struct conforms Decodable protocol and use a JSONDecoder

That’s pretty straightforward right?

What’s happening is that the decoder is mapping the json’s fields with the Post object’s properties that have the exaclty same names.

In order to map object’s properties with json’s field that have different names we need to tell the decoder where to go searching. We can do that with a simple enum named CodingKeys that conforms CodingKey where the raw values of the cases match the json properties names.

One important thing to notice is that the name of the enum must be CodingKeys, if we want to change is we need to provide a custom init.

Beside the CusomJsonKeys enum that’s is pretty self-explanatory one thing to notice is that in this case we need to provide an init(from decoder: Decorer)throw.

In this method we provide the decoder with our custom keys in order to get a container that is an instance ofKeyedDecodingContainer. You can think the container as some kind of dictionary.

We can agree that the syntax is a little bit messy and not very readable but I’ve done this extension to make things easier.

By adding this extension you will be able to use the KeyedDecodingContainer just as you would do with a dictionary.

Now we also don’t need to tell the property type because it will be inherited. Neat.

Nested objects

Nothing changes with nested object, the only think you need to remember is that even the nested objects need to conform the Decodableprotocol and need to provide a custom init where needed.

To infinity and beyond

That’s pretty much everything you need to now but keep in mind those things:

  • Automatching” is only available with type values such as struct, if you want your class to work with Codable you have to always provide a custom init.
  • You can decode array and dictionary as well, just use decoder.decode([YourObjectInAnArray].self, from: jsonData) for array and decoder.decode([YourKey: YourObjectInArray].self, from: jsonData)for dictionaries.
  • If you need a custom coder in addiction to JSONCoder and PropertyListCoder you can write your own!

Download

You can download here a playground where you can find a lot of examples of decoding simple and complex objects.

Conclusions

I know I almost only talked about decoding but I think it’s the most interesting part and also the coding counter part is pretty much alike.

I leave the reader the pleasure of discovering the rest by himself :)