Complex Json to Swift Codable

142 views Asked by At

I'm facing a problem when try to "cast" my JSON Response to my struct.

My JSON response:

{
    "data" =     {
        "answers" =         {
            "10" = "Not";
            "11" = "Not";
        };
        "company" = 1;
        "name" = "Name";
        "profile" =         {
            "email" = "[email protected]";
            "first_name" = "First name";
            "identity_document" = 12345678;
        };
    };
    "msg_code" = 0;
    "msg_text" = "Success";
}

My struct:

struct LoginResponse: Codable {
    let answers: Dictionary<String, String>?
    let company: Int?
    let name: String?
    let profile: Profile?
    
    private enum CodingKeys: String, CodingKey{
        case answers = "answers"
        case company = "company"
        case name = "name"
        case profile = "profile"
    }
}

struct Profile: Codable{
    let email: String?
    let first_name: String?
    let identity_document: String?
    
    private enum CodingKeys: String, CodingKey{
        case email = "email"
        case first_name = "first_name"
        case identity_document = "identity_document"
    }
}

My code to decode:

Alamofire.request("myURL", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON{
                response in
                switch response.result
                {
                case .success(let json):
                    let login = try! JSONDecoder().decode(LoginResponse.self, from: json as! Data)
                    SVProgressHUD.dismiss()
                case .failure(let error):
                    self.showAlertOk(title:"Alert!", message: "Response Error", handlerOK: { action in print("error")})
                    SVProgressHUD.dismiss()
                }
            }

The line:

let login = try! JSONDecoder().decode(LoginResponse.self, from: json as! Data)

it's the result to fix the previous version:

let login = try! JSONDecoder().decode(LoginResponse.self, from: json)

or

let login = try! JSONDecoder().decode(LoginResponse.self, from: json.data(using: .utf8)!)

The logcat said,

Could not cast value of type '__NSDictionaryI' (0x7fff87b9d5f0) to 'NSData' (0x7fff87b9c088).

Any advice? I understand that I have to change as! Data for as Dictionary, but I didn't find any example how to do it.

1

There are 1 answers

0
vadian On BEST ANSWER

Two fatal issues:

  1. The root object (the dictionary with keys data, msg_code and msg_text) is missing

    struct Root: Codable {
        let data : LoginResponse
    }
    
  2. You have to replace responseJSON with responseData to get the raw data, responseJSON returns a Swift array or dictionary.

    Alamofire.request("myURL", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseData {
    
    ...
    
    case .success(let data):
    let login = try! JSONDecoder().decode(Root.self, from: data)
    

And don't try!, catch the error and handle it.