Swift - Decodable 无法使用可选值进行解码
Swift - Decodable fails to decode with an optional value
我正在尝试向后端发出简单的登录请求。后端 returns 一个 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 = "User not registered";
但是对于带有访问令牌的响应,例如:
"access_token" = TheAccessToken;
code = 200;
message = "Login successfully";
AuthResponse
对象没有解码失败。
为什么会这样?这与 accessToken
属性 是可选的这一事实有关吗?我也尝试过覆盖解码初始化器并实现 decodeIfPresent(_:forKey:)
并展开 属性 但两者似乎都没有帮助。
提前致谢。
代码不能因您提供的信息而失败。
请打印 catch
块中的 error
实例并将其添加到您的问题中。
然而,一个复杂的替代方案——没有任何可选——是一个具有关联类型的枚举。它 returns 成功时的令牌和失败时的代码和消息
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)
}
我正在尝试向后端发出简单的登录请求。后端 returns 一个 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 = "User not registered";
但是对于带有访问令牌的响应,例如:
"access_token" = TheAccessToken;
code = 200;
message = "Login successfully";
AuthResponse
对象没有解码失败。
为什么会这样?这与 accessToken
属性 是可选的这一事实有关吗?我也尝试过覆盖解码初始化器并实现 decodeIfPresent(_:forKey:)
并展开 属性 但两者似乎都没有帮助。
提前致谢。
代码不能因您提供的信息而失败。
请打印 catch
块中的 error
实例并将其添加到您的问题中。
然而,一个复杂的替代方案——没有任何可选——是一个具有关联类型的枚举。它 returns 成功时的令牌和失败时的代码和消息
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)
}