我使用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?.ret
和loginRequest?.text
很好,但是loginRequest?.data.email
,loginRequest?.data.zip
...为空(无)
答案 0 :(得分:2)
如果CodingKeys
的{{1}}名称与api响应中的enum
键相同,则无需声明variable
type
。例如,在您的情况下,您将所有变量(在json
和UserDataRootClass
内)命名为其各自的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?
}
。