我正在尝试向后端提出一个简单的登录请求。仅当登录成功后,后端才会返回由状态码,每次字符串消息和访问令牌组成的JSON对象。
为此,我创建了以下struct
:
struct AuthResponse: Decodable {
enum CodingKeys: String, CodingKey {
case code, message
case accessToken = "access_token"
}
let code: Int, message: String, accessToken: String?
}
当登录失败并且服务器未发送访问令牌时,AuthResponse
对象将设法正确解码,nil
属性的accessToken
就像我希望如此。例如,对于以下响应,解码成功:
code = 400;
message =“用户未注册”;
但是对于带有访问令牌的响应,例如:
“ access_token” = TheAccessToken ;
代码= 200;
message =“登录成功”;
AuthResponse
对象不会解码。
为什么会这样?这与accessToken
属性是可选属性有关吗?我还尝试了覆盖解码初始化程序并实现decodeIfPresent(_:forKey:)
并展开属性,但两者似乎都没有帮助。
预先感谢。
答案 0 :(得分:2)
代码一定不会因您提供的信息而失败。
请在error
块中打印catch
实例,并将其添加到您的问题中。
尽管如此,一个复杂的替代方法(没有任何可选方法)是带有关联类型的枚举。成功返回令牌,失败返回代码和消息
enum AuthResponse: Decodable {
case success(String), failure(Int, String)
private enum CodingKeys : String, CodingKey { case code, message, accessToken = "access_token" }
init(from decoder : Decoder) throws
{
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
let code = try container.decode(Int.self, forKey: .code)
if code == 200 {
let token = try container.decode(String.self, forKey: .accessToken)
self = .success(token)
} else {
let message = try container.decode(String.self, forKey: .message)
self = .failure(code, message)
}
}
}
}
并使用它
let result = try JSONDecoder().decode(AuthResponse.self, from: data)
switch result {
case .success(let token): print(token)
case .failure(let code, let message): print(code, message)
}