【发布时间】:2020-03-12 09:34:00
【问题描述】:
我在尝试将嵌套的 json 响应解析为自定义可解码响应类时收到 nil。
自定义响应类:
class User: Decodable, Encodable {
var name: String?
var email: String?
var token: String?
enum CodingKeys: String, CodingKey {
case name
case email
case token
}
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try? container.decode(String.self, forKey: .name)
self.email = try? container.decode(String.self, forKey: .email)
self.token = try? container.decode(String.self, forKey: .token)
}
}
class ResponseData: Decodable {
let body: [User]?
enum CodingKeys: String, CodingKey {
case users
case body
}
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let response = try container.nestedContainer(keyedBy:CodingKeys.self, forKey: .body)
self.body = try response.decode([User].self, forKey: .users)
}
}
class ResponseRoot: Decodable {
let data : ResponseData?
enum CodingKeys: String, CodingKey { case data }
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.data = try? container.decode(ResponseData.self, forKey: .data)
}
}
用于解析的 Json 响应,
{
"status": "success",
"errorMessage": null,
"data": {
"headers": {},
"body": [
{
"name": "Alex",
"email": "alex@b.c",
"password": "1234",
"token": "1234",
"loginStatus": 0
},
{
"name": "Einstein",
"email": "e@b.c",
"password": "1234",
"token": "A valid token",
"loginStatus": 1
}
],
"statusCode": "OK",
"statusCodeValue": 200
}
}
Alamofire 呼叫,
Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.queryString, headers: nil)
.validate()
.responseJSON { response in
switch (response.result) {
case .success( _):
do {
let users = try JSONDecoder().decode(ResponseRoot.self, from: response.data!) // getting users = nil
completion((users.data?.body!)!)
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
completion([])
}
case .failure(let error):
print("Request error: \(error.localizedDescription)")
completion([])
}
现在,let users = try JSONDecoder().decode(ResponseRoot.self, from: response.data!) 不会创建任何异常,但 users 为零。
【问题讨论】:
-
Statuscode 400 是服务器错误,与解码部分无关。并且永远不要打印
localizedDescription的DecodingError。你扔掉了全面的错误信息。 -
在.failure的情况下不是HTTP请求的请求错误吗? API 调用失败,因此它不执行解码行
-
我得到了有效的响应数据
-
@aiwiguna & @vadian,我更新了帖子。错误来自以前的日志。我为我的误会道歉。但现在我收到了
nil。 -
看起来您可以删除一半的代码。 Codingkeys 并不是真正需要的,因为您的变量名称与键相同。结构内部也不需要初始化器。您所要做的就是调用 JSONDecoder.decode(ResponseRoot, from: data) 它应该可以工作。
标签: json swift nested alamofire decodable