Swift 4 introduced tons of new features and improvements. The one I’m most excited with and have been missing it from the absolute beginning is definitely the Codable protocol.
What Codable does is it encodes or decodes your objects to external representation, for example JSON. It works with primitive types (Int, String and Float etc.), some Foundation types (Data, URL, Date etc.) as well as with arrays, dictionaries and optionals (if they contain Codable types of course). It even works with enums!
Hint: Codable combines two protocols: Encodable and Decodable.
Those two protocols are really simple. They each contain a single requirement. One for encoding and one for decoding the object.
Basic example
Let’ presume we have a structure like this:
We can then encode the Sword objects as simple as:
This creates a Data object that contains this raw JSON:
There are two things to notice in the example above:
- We didn’t have to implement the protocol requirements
- The keys in the JSON are the same as the variable names.
The reason for that is that the compiler creates the basic implementation of those two requirements for us.
Manually encoding and decoding
Encoding
If we want to manually specify the keys that the variable names we have do two things:
- Define the coding keys which we want to use:
- Implement the encode method:
When encoding/decoding with our set of keys we need to define them with an enumeration that inherits from String and CodingKey. The string raw values will be our new keys.
Encoding is happening using the Encoder with the previously defined keys. We then try to encode/decode each key from the container.
Let’s encode it again using the same two lines:
The result is:
Our custom keys are applied!
Decoding
Decoding is very similar to encoding. The requirement is only the [cci language=”swift”]init(from decoder: Decoder) throws[/cci] initializer. The implementation for the above [cci language=”swift”]Sword[/cci] struct and our [cci language=”swift”]CodingKeys[/cci] is as follows:
We simply try to decode each value by specifying the type and the key. If any of them fails, the whole initializer fails and throws an exception.
The decoding code looks as follows (let’s presume we have the JSON in string):
We successfully decoded our JSON string to our Sword object!
The whole source code can be found here.