How to write strong models for swift Codable and reusing that model again.

Sajjad Sarkoobi
4 min readAug 20, 2018

In this post, I’m not going to write about what the codable protocol is and how to use it! instead of that, I’m going to tell you how to write the best model for it in the swift language in a very short story. so let’s go…

if you are new in codable, I strongly recommend to learn more about it and then come back here and read the rest.

Most of you may be use decodable for deserializing JSON files. but how about if you want to use that model again in your project as a list or an array. or just want to create a global instance array from that model in your project and do mapping a lot of times. unfortunately, many junior developers are going to create another model struct and use that one. but they may struggle with optionals or forced unwrapping.

assuming this JSON file:

{
"name" : "John",
"lastName" : "Doe",
"age" : 27
}

in this JSON file we have a simple user data. so we are starting with simple model struct:

struct user_Model:Codable {
let name:String?
let lastName:String?
let age:Int?
}

in this model we are using “let” and we have to put optional “?” at the end of each parameter for avoiding deserialization error. if that parameter doesn’t exist in that JSON file it will return “nil” instead of that. so we should always handle “nil”. :( in another hand, you can’t make another instance of that model with safe unwrapping. this will happen:

(testUser?.name)! this is so Wrong.

maybe you say that we can use Class instead of struct and then using:

required init(<#parameters#>) {
<#statements#>
}

and initialize each parameter there. like this :

class user_Model:Codable {
var name:String
var lastName:String
var age:Int

required init() {
self.name = ""
self.lastName = ""
self.age = 0
}
}

but when we are going to decode a JSON file with JSONDecoder()

let decoder = JSONDecoder()
let product = try decoder.decode(user.self, from: json)

its not going to map correctly. :( !

so the best way to write a powerful model for codable protocol is to have:

init(){}
init(from decoder: Decoder) throws{
}

and from decoder we should use container(keyedBy:) then safely we are going to decode a value if it is presented in our JSON file, if that parameter isn’t there it will assign our defined default value. :) !

so our complete model will be something like this:

supporting codable and also you can use and create instance from it anywhere.

this is so safe now. :)

But how about this kind of JSON files:

as you know we need another Model for Joined here, so how we can handle it?! we should just create another model for that and do the same things. then in user_Model we can safely reference to the joined model for deserializing joined objects.

I'm not going to make this post longer and put the codes directly here. I know all of you are smart enough to figure it out. :)

so at the end with this kind of model we can create instance of that model again in our program without any problem.

Thank you for reading.

this is my other post about UserDefaults:

--

--