json - Swift - Decodable 无法使用可选值解码
问题描述
我正在尝试向后端发出简单的登录请求。后端返回一个 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
例如,以下响应的解码成功:
代码 = 400;
message = "用户未注册";
但是对于带有访问令牌的响应,例如:
"access_token" = TheAccessToken ;
代码 = 200;
message = "登录成功";
AuthResponse
对象没有解码失败。
为什么会这样?这是否与该accessToken
属性是可选的事实有关?我也尝试过覆盖解码初始化程序并实现 adecodeIfPresent(_:forKey:)
并解包该属性,但两者似乎都没有帮助。
提前致谢。
解决方案
代码不能因您提供的信息而失败。
请打印块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)
}
推荐阅读
- angular - Angular 6 - 无法转换 DatePipe
- karate - 如何使用外部变量过滤地图列表
- python - 按周分组的 Python matplotlib 条形图
- c++ - 如何在析构函数期间同步
- iot - 我如何订阅 azure iot hub 设备到设备通信中的主题
- ruby-on-rails - Capybara 功能测试 ActionView::Template::Error
- android - Bintray 上的 Android 库缺少源和 javadoc
- kotlin - 是否可以期望来自 AxonFramework 中非轴突类的调度命令
- python - 如何从Python列表中仅获取特定项目
- javascript - ajax post应用的问题