Swift 4: Coding and Decoding JSON structure with the Encodable and Decodable protocols

In this new tutorial you'll learn how to decode and encode a json object using the new Encodable and Decodale protocols (defined in the new Codable type), and how to do a custom decoding by doing some data manipulation during the json object extraction. You will see three different examples that will explain you how it is so easy with swift 4 to do the coding and decoding json process.

What's new

Swift 4 has introduced the JSONDecoder() and JSONEncoder() functions, used to do the decoding and encoding operation and the new Codable type, that contains the Encodable and Decodable protocols. When you define your custom object, you can use one of these protocol (or the codable one if your struct needs to do both the decoding and encoding process).

How to decode a JSON object into a swift 4 custom struct

Let's define or custom simple struct. In this example we'll use a json array, with different objects (name - String, id - int and an optional one).

struct MyStruct_1 : Decodable{
var name : String
var id : Int
var some_extra_param : String? = nil

}

This struct will implement the Decodable protocol. When you have to decode your json object into your custom swift 4 struct, you'll just have to call the JSONDecoder() function.

let Arr = try? JSONDecoder().decode([MyStruct_1].self, from: json_1)

The square brakets are required because we want to decode an array. This function will directly map the json data into your custom struct array. If the json decoding process fails, the final variable will be nil.

Let's do a custom JSON decoding

Now, let's do some data manipulation during the decoding process. The server send the id as string, but we want to map it into an integer. Moreover we want to fill some optional values if empty with defaults one.

Let's define our custom structs and the Codingkeys string values:

struct MyStruct_2{
var name:String
var id:Int
var some_extra_param:String? = nil

enum keys:String,CodingKey {
case name
case id
case some_extra_param
}
}

Let's implement now the Decodable protocol:

extension MyStruct_2 : Decodable{
init(from decoder:Decoder) throws{
let values = try decoder.container(keyedBy: keys.self)
name = try values.decode(String.self, forKey: .name)
some_extra_param = try? values.decode(String.self, forKey: .some_extra_param)
let id_as_string = try values.decode(String.self, forKey: .id)
id = Int(id_as_string)!
if(some_extra_param == nil) {
some_extra_param = "not_defined"
}
}
}

The init(from decoder:Decoder) function is called during the decoding process. Here you can do the data manipulation.

Let's do the JSON encoding using the Codable protocol

It's now time of the encoding process. You'll just have to define your struct using the Codable protocol. Then you'll just have to call the JSONEncoder().encode function. Swift will then do all the work.

struct MyStruct_3 : Encodable{
let name:String
let id:Int
}


if let json_data = try? JSONEncoder().encode(Arr3){
if let json_string = String(data:json_data, encoding: .utf8)
{
print(json_string)
}
}

Here you can download the playground example with the tree different examples:

Download