Skip to content
This repository has been archived by the owner on Mar 10, 2022. It is now read-only.

Adding support for Swift.Codable #166

Open
kjoneandrei opened this issue Mar 16, 2018 · 0 comments
Open

Adding support for Swift.Codable #166

kjoneandrei opened this issue Mar 16, 2018 · 0 comments

Comments

@kjoneandrei
Copy link

kjoneandrei commented Mar 16, 2018

Add support for Swift.Codable that can be used with both Alamofire and URLSession

https://trello.com/c/6AUldeXS/99-codable-vs-serpent
https://trello.com/c/iqT6jV2t/107-8-alamofire-vs-urlsession

Swift.Codable vs Serializable

Using Swift.Codable reduces quite a bit of the boiler plate code needed by our data struct's in ordeer to comply to Serializable.

With Swift.Codable, if the server response data contains matching keys with our variable names, the only code needed to conform to Swift.Codable is:

import Foundation

struct CategoryItem: Codable {
    var title = ""
    var id = ""
}

while if the variable names do not match conforming to Swift.Codable is done as follows:

import Foundation

struct CategoryItem: Codable {
    var title = ""
    var id = ""
        
    init(from decoder: Decoder) throws {
        let map = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try map.decode(String.self, forKey: .id)
        self.title = try map.decode(String.self, forKey: .title)
    }
    
    private enum CodingKeys: String, CodingKey {
        case id
        case title
    }
}

when trying to Swift.Decode or Swift.Encode optionals we should do them by using try? instead of try :

import Foundation

struct CategoryItem: Codable {
    var title: String?
    var id = ""
       
    init(from decoder: Decoder) throws {
        let map = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try map.decode(String.self, forKey: .id)
        self.title = try? map.decode(String.self, forKey: .title)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode (id, forKey: .id)
        try? container.encode (title, forKey: .title)
    }
    
    private enum CodingKeys: String, CodingKey {
        case id
        case title
    }
}

As well we can use an Enum and conform it to Codable

enum Type: String, Codable {}

If needed Decoding an Enum can be done like this:

enumVar =  try map.decode(Type.self, forKey: .enumVar)

Swift.Codable and URLSession

Opening a dataTask with URLSession and decoding the data can be done fairly easy now by doing the following:

guard let urlComponent = urlComponent, let url = urlComponent.url?.appendingPathComponent("breaking") else { return } let dataTask = urlSession.dataTask(with: url, completionHandler: urlSession.decode(completion)) dataTask.resume()

where urlComponent is of type URLComponents? and urlSession.decode(completion) is introduced in the upcoming Pull Request. As the completion parameter we can pass a DResult<Value>, where Value is a Generic Type and can contain stand alone objects or Arrays of objects.

Also in order to facilitate the paginated requests there is added a DPaginatedResponse (DecodedPaginatedResponse) that can be added in the completion as follow: completion: @escaping (DResult<DPaginatedResponse<Value>>)

Pull Requst: #167

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant