使用Alamofire解析可编码的响应

时间:2019-08-26 06:20:09

标签: ios json swift alamofire codable

我使用Alamofire框架,但我不明白为什么下面的变量为空。

json:

{
    "ret": true,
    "text": "Oke!",
    "data": {
        "email": “test@mail.com”,
        "nev": "text",
        "zip": "1234",
        "city": "London",
        "street": "text",
        "phone": "5555555555",
        "gdpr": "2"
    }
}

UserDataRootClass.swift:

struct UserDataRootClass : Codable {

        let data : UserDataData?
        let ret : Bool?
        let text : String?

        enum CodingKeys: String, CodingKey {
                case data = "data"
                case ret = "ret"
                case text = "text"
        }

        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                data = try? UserDataData(from: decoder)
                ret = try values.decodeIfPresent(Bool.self, forKey: .ret)
                text = try values.decodeIfPresent(String.self, forKey: .text)
        }

}

UserDataData.swift:

struct UserDataData : Codable {

        let city : String?
        let email : String?
        let gdpr : String?
        let nev : String?
        let phone : String?
        let street : String?
        let zip : String?

        enum CodingKeys: String, CodingKey {
                case city = "city"
                case email = "email"
                case gdpr = "gdpr"
                case nev = "nev"
                case phone = "phone"
                case street = "street"
                case zip = "zip"
        }

        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                city = try values.decodeIfPresent(String.self, forKey: .city)
                email = try values.decodeIfPresent(String.self, forKey: .email)
                gdpr = try values.decodeIfPresent(String.self, forKey: .gdpr)
                nev = try values.decodeIfPresent(String.self, forKey: .nev)
                phone = try values.decodeIfPresent(String.self, forKey: .phone)
                street = try values.decodeIfPresent(String.self, forKey: .street)
                zip = try values.decodeIfPresent(String.self, forKey: .zip)
        }

}

NetworkManager.swift:

func postLogin(urlString: String, completion: @escaping (UserDataRootClass?) -> Void) {
        Alamofire.request(urlString).response {
            response in
            guard let data = response.data else { return }
            do {
                let decoder = JSONDecoder()
                let loginRequest = try decoder.decode(UserDataRootClass.self, from: data)
               completion(loginRequest)
            } catch let error {
                print(error)
                completion(nil)
            }
        }
    }

LoginViewController.swift:

let networkManager = NetworkManager()
networkManager.postLogin(urlString: "http://demo.com") { (loginRequest) in

if((loginRequest?.ret)!) {
   print(loginRequest) // -> for log
   print(loginRequest?.data.phone)
   }

}

日志:

  

UserDataRootClass(data:Optional(.UserDataData(gdpr:nil,email:nil,   邮递区号:nil,nev:nil,电话:nil,城市:nil,街道:nil)),ret:   可选(真),文本:可选(“ Oke!”))

loginRequest?.retloginRequest?.text很好,但是loginRequest?.data.emailloginRequest?.data.zip ...为空(无)

1 个答案:

答案 0 :(得分:2)

如果CodingKeys的{​​{1}}名称与api响应中的enum键相同,则无需声明variable type。例如,在您的情况下,您将所有变量(在jsonUserDataRootClass内)命名为其各自的UserDataData键,因此可以删除这些枚举。

json

此外,除非必须对任何属性进行一些自定义,否则您无需实施struct UserDataData : Codable { let city : String? let email : String? let gdpr : String? let nev : String? let phone : String? let street : String? let zip : String? } struct UserDataRootClass : Codable { let data : UserDataData? let ret : Bool? let text : String? }