CRey
CRey

Reputation: 1160

How to decode this using JSONDecoder and Swift 4 Decodabale class

I have decoded this using JSONSerialization. But for my own knowledge and the maintenance of my code. I would like to know how to decode this.

This is what I have so far:

let urlString = "site deleted" + "/DataSource/Mobile/?Action=MyProfile&uid=" + uid + "&uuid=" + uuid
    guard let url = URL(string: urlString) else {return}
    URLSession.shared.dataTask(with: url) { (data, _, error) in
        if let err = error {
            print("Handle MyProfileJSON error: ", err)
        }
        guard let data = data else {return}
        do {
            // swift 4.2 but we cant use it right now
            let profile = try JSONDecoder().decode(RequestResult.self, from: data)
        print(profile)
        completion(profile)
    } catch let err {
        print("Handle Decoder Error: ", err)
    }

}.resume()

I'm not too worried about the cases but this is what I have so far. I know the case I use is not the convention, that's why I did this with JSONSerialization so I can use camelCase. If you can help me convert it to camelCase too that would be amazing but my focus is to Decode this using Decodable class. Thanks a lot, guys.

And this are my structs:

struct RequestResult: Decodable {
    var Action: String?
    var Params: [String: String]?
    var DATA: [String: String]?
}

struct Params: Decodable {
    var Action_get: String?
    var uid_get: String?
}

struct DATA: Decodable {
    var Id: String?
    var UserCode: String?
    var HomePhone: String?
    var Mobile: String?
    var WorkPhone: String?
    var Email: String?
    var AltEmail: String?
    var UnitNo: String?
    var StreetNo: String?
    var StreetName: String?
    var City: String?
    var StateProvince: String?
    var Country: String?
    var ZipPostalCode: String?
}

Upvotes: 0

Views: 381

Answers (1)

vadian
vadian

Reputation: 285069

The structure of the JSON is very clear

  • The root object RequestResult contains a string and two dictionaries.
  • The dictionaries are replaced by structs.
  • The CodingKeys are useful to rename the keys to more meaningful and naming convention conforming names. The left side of an enum case is the struct member name, the right side the original JSON key.
  • A struct member name must match the dictionary key (or the mapped CodingKey).
  • The struct names are arbitrary.
  • All struct members can be declared as constants (let) and as non-optional if the JSON contain always the keys.

    struct RequestResult: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case action = "Action", params = "Params", data = "DATA"
        }
    
        let action: String
        let params: Parameter
        let data: UserData
    }
    
  • The dictionary for key Params will be renamed to Parameter and DATA to UserData

    struct Parameter: Decodable {
        private enum CodingKeys : String, CodingKey {
            case action = "Action_get", uid = "uid_get"
        }
    
        let action: String
        let get: String
    }
    
    struct UserData: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case id = "Id", userCode = "UserCode", homePhone = "HomePhone"
            case mobile = "Mobile", workPhone = "WorkPhone", email = "Email"
            case altEmail = "AltEmail", unitNo = "UnitNo", streetNo = "StreetNo"
            case streetName = "StreetName", city = "City", stateProvince = "StateProvince"
            case country = "Country", zipPostalCode = "ZipPostalCode"
        }
    
        let id: String, userCode, homePhone, mobile: String
        let workPhone, email, altEmail, unitNo: String
        let streetNo, streetName, city, stateProvince: String
        let country, zipPostalCode: String
    }
    

Upvotes: 1

Related Questions