Saturday, July 10, 2021

What is Codable in Swift

Introduced in Swift 4, the Codable API enables us to leverage the compiler in order to generate much of the code needed to encode and decode data to/from a serialized format, like JSON. Codable is actually a type alias that combines two protocols — Encodable and Decodable



Introduced in Swift 4, the Codable API enables us to leverage the compiler in order to generate much of the code needed to encode and decode data to/from a serialized format, like JSON.


Codable is actually a type alias that combines two protocols — Encodable and Decodable — into one. By conforming to either of those protocols when declaring a type, the compiler will attempt to automatically synthesize the code required to encode or decode an instance of that type, which will work as long as we’re only using stored properties that themselves are encodable/decodable — such as when defining this User type:


struct User: Codable {

    var name: String

    var age: Int

}


By only adding that single protocol conformance, we’re now able to encode a user instance into JSON Data by using a JSONEncoder:


do {

    let user = User(name: "John", age: 31)

    let encoder = JSONEncoder()

    let data = try encoder.encode(user)

} catch {

    print("Whoops, an error occured: \(error)")

}


Since encoding a value is an operation that could potentially throw an error, we need to call encode() prefixed by the try keyword, and handle any error that was thrown. In the above example, we encapsulate our encoding code in a do block, and use catch to catch any error that was encountered.


Now that we have encoded a value into data, let’s see if we can decode it back into a User instance. To do that, we use a JSONDecoder, by passing it our data while telling it what type we’re interested in decoding:


let decoder = JSONDecoder()

let secondUser = try decoder.decode(User.self, from: data)


However, sometimes the JSON format we’re dealing with doesn’t exactly match the structure that want our corresponding Swift type to have. For example, the JSON representing one of our User values might look like this:



{

    "user_data": {

        "full_name": "John Sundell",

        "user_age": 31

    }

}


introducing a new type that we’ll specifically use for encoding and decoding. That way we can make that type use the same structure as our JSON does, without affecting our actual model code. Here’s what such a type could look like for the above JSON format:




extension User {

    struct CodingData: Codable {

        struct Container: Codable {

            var fullName: String

            var userAge: Int

        }


        var userData: Container

    }

}


We’ll then add a convenience method to our new User.CodingData type, that’ll let us quickly convert a decoded value into a proper User instance, like this:


extension User.CodingData {

    var user: User {

        return User(

            name: userData.fullName,

            age: userData.userAge

        )

    }

}



References

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

No comments:

Post a Comment