なんとかするから、なんとかなる

エンジニア関係のことを書きます

iOS How to use the Decodable

Introdution

This article show the basically usage of Decodable Protocol.  

What's the Decodable

The Decodable give us an easy way to convert the JSON Data type to Class or Struct.   Thanks for the Decoable protocol, developer could access each member value easily without any string key.   String Key oftem make us a typo.  It sometimes annoyed me ; )  

Let's try it!

Let's try to define the Docodable Struct

struct SomeStruct: Decodable {
    var value: String
    var version: Int
    
    enum CodingKeys: String, CodingKey {
        case value
        case version = "app_version"
    }
}

 

Let's try to Decode the JSON data type

let json: Data = """
{
    "value": "GoodString",
    "app_version": 5
}
""".data(using: .utf8)!
let someStruct = try? JSONDecoder().decode(SomeStruct.self, from: json)

 

Details

At firts, apply the Decodable Protocol to Struct type.   Implement the enum of CodingKeys.   That's All!   CodingKeys need to include each values's name.   It the values name is different from the JSON Key value, you can declear the raw value in declaring of CodingKeys enum.   Important thing is that each values need declear in var instead of let.   If you declear the value in let, the decoding process allways return nil. ;)   If the some JSON key has optional key, it's ok to clear the member value with optional "?" .  

struct SomeStruct: Decodable {
    var value: String
    var version: Int
    var exception: Int?
    
    enum CodingKeys: String, CodingKey {
        case value
        case version = "app_version"
    }
}

 

Decode the JSON which has another struct.

Let's try to decode the JSON Data type which has another struct.   In this case, SomeStruct has InnerStruct Array.  

Declear the Decodable

 

struct SomeStruct: Decodable {
    var value: String
    var version: Int
    var inners: [InnerStruct]
    
    enum CodingKeys: String, CodingKey {
        case value
        case version = "app_version"
        case inners = "inner_structs"
    }
}
 
struct InnerStruct: Decodable {
    var index: Int
    var name: String
    
    enum CodingKeys: String, CodingKey {
        case index = "inner_index"
        case name = "inner_name"
    }
}

  If you would like to clear the InnerStruct as is, it's OK to clear it directly.

struct SomeStruct: Decodable {
    var value: String
    var version: Int
    var inner: InnerStruct
    
    enum CodingKeys: String, CodingKey {
        case value
        case version = "app_version"
        case inners= "inner_struct"
    }
}

 

Let's try to Decode the JSON data type

 

let json: Data = """
{
    "value": "GoodString",
    "app_version": 5,
    "inner_structs": [{
        "inner_index": 1,
        "inner_name": "myName"
    }]
}
""".data(using: .utf8)!
let someStruct = try? JSONDecoder().decode(SomeStruct.self, from: json)

 

Wrap up!

The decodable is easy and useful !!