All About Codable in Swift (Part 1)
In this blog we will cover
- Why we need Codable (Background)
- What is Codable, Encodable and Decodable
- Decode plain json to Swift custom model and vice versa
- Coding Keys (Keys you don’t want to parse)
- Keys Exists in json but not in the Model
- Key in model can exists or not in your json
- Model and json with different structure keys (Decoding)
- Model and json with different structure keys (Encoding)
- Custom Decoding With Key may or maynot exists in Json
- Working with Type Mismatch

Background
Every application talks to the server and use the response to display data. If your application is in swift they will use the Swift data type (Swift datatype compose object) and your server is using the Java data type so there should be some standardize data type that both know so they can talk to each other. To solve this problem we have two most common data interchange format JSON and XML
Codable
Introduced in Swift 4, Codable in Swift is used to encode and decode custom data formats, such as JSON, to native Swift objects and vice versa.
Codable
is actually a type alias that combines two protocols —Encodable
andDecodable
Encodable Protocol
Purpose is to convert Swift datatype to Json format
Decodable Protocol
Purpose is to convert Json format to Swift datatype
Getting Started
As shown in Figure 1 we did a few things
- Created a Swift datatype compose object we called it custom data Type and we conform to
Codable
protocol - Created JSONDecoder object facilitates the decoding of JSON into semantic types (type conforming to
Decodable
protocol). That’s why our . custom type conforming to Codable protocol.Codable
is a type alias for the `Encodable
` and `Decodable
` protocols. decoder.decode
converted json into custom type as shown in Figure 1.

As shown in Figure 2 we encode custom data type to json object

Let’s say server is sending different keys . name
key is updated with the nameUp
in response object, This means that the field names in the JSON will no longer match up with the property names in your type and it is giving keyNotFound error and application will crash.

You can define custom coding keys to supply coding names for your properties. Now it expect nameUp
key from json and it value will be store on name
field of the User data type

If your expect same key in json then you don’t need to provide enum rawvalue because raw value for a particular enumeration case is always the same
CodingKeys
is the special enum mentioned above. It conforms toCodingKey
and hasString
raw values.

Keys you don’t want to parse
If this enum exists, only the cases present here will be used for encoding and decoding, so even if your property doesn’t require mapping. As shown in Figure 6 notToParseType
key is coming in json but it doesn't decode since we didn't specify in our enum

If you specify case and you don’t have in your stored property of the model it will throw an error. Case you add in enum should contain in your model

Keys Exists in json but not in the Model
As shown in Figure 8 Decoder take model key and search in json if it found all the key it created a model and don’t look additional field in json. So in this case it will not crash the application

Key in model can exists or not in your json
As shown in Figure 9 keyExistorNot
may or maynot come in json so we make this property as an optional or assign some initial value. In this way our decoding will not fail

As shown in Figure 10 our model is hierarchical and json we expect is flat so how can we parse it

Model and json with different structure keys (Decoding)
Now json doesn’t match with your model structure, so you need to write our own decoding logic and describe how to decode each User
and company
stored property.
As shown in Figure 11 our json is flat where companyName
and companyId
are coming in flat structure but in our model we don’t have this property instead of this we have another custom model Company
. Inside “company” were two more keys, “name” and “id”, so we created CompanyCodingKeys
for that few things to note
- By writing your own decoder you can specify container in our case we first created container with
CodingKeys
and we only decodename
,id
andtype
from json Then we createdCompanyCodingKeys
and we expectcompanyName
andcompanyId
in json since it exists in enum compiler is happy

As shown in Figure 12 we removed custom decoder and enum and want automatic decoding of codable it failed because it expect all non-optional key to be present in json

Rule of Thumb 1:
Decoder by default looks
CodingKeys
enum and try to give initial value if succeed it will not throw any error
As shown in Figure 13 decoder list down all the enum keys in our case name
, id
, type
, company
and notToParse
and find keys in json and it found name, id and type
now it takes value from json and initialize these property. It didn’t able to find company and notToParse
properties in json , it first check whether it is optional if it is optional it assign nil and if it not optional it check whether it has some default value if that not the case it will throw an error. In our case these two properties have default value so it will not throw an error

Model and json with different structure keys (Encoding)
As shown in Figure 14 server expecting flat json since our model is hierarchical it created hierarchical json company and in that use the same name property as a key


As shown in Figure 16 we created a flat json from hierarchical model structure using custom encoding

Custom Decoding With Key may or maynot exists in Json
As shown in Figure 17 we specified mayExists
as an optional but it failed since we are decoding in custom decoder and it expect key to be there

As shown in Figure 18 we expect decodable to be optional in our custom decodable implementation instead it is failing because it expect this property from json

To solve his problem we have a method decodeIfPresent
as name suggest it will decode if key exists in json.
decodeIfPresent →
Decodes a value of the given type for the given key, if present.This method returns `nil` if the container does not have a value

As shown in Figure 20 if key exists in json but with null value your decoding will be failed. There are two solutions for this problem either you can use decodeIfPresent
or expect decoding can return nil value as shown in Figure 21



Working with Type Mismatch
As shown in Figure 22 company model Id
we expected Int
but server is sending String

We fix this issue by decode it as String
and type cast it as Int .
This is also the reason we need to implement our own custom decoder

Useful Links
https://www.swiftbysundell.com/basics/codable/https://www.swiftbysundell.com/basics/codable/