ios - 如何使用 Codable 处理 JSON 响应失败的情况?

标签 ios json swift codable

我有一些从服务器获取的 JSON 响应。在成功的情况下,它可能是这样的:

{
  "success": true, 
  "data": [
    {
       /// something here 
    }
  ]
}

如果所有服务器响应都成功,那么解析该 JSON 就会非常容易。但我们也有失败案例,例如:

{
  "success": false, 
  "msg": "Your session expired",
  "end_session": true 
}

这意味着我们需要处理两种情况。正如您所注意到的,诸如 success、msg 之类的属性可能会出现在任何响应中。为了解决这个问题,我创建了以下结构:

struct RegularResponse<T: Codable>: Codable {
let success: Bool
let msg: String?
let endSession: Bool?
let data: T?

enum CodingKeys: String, CodingKey {
    case success, msg, data
    case endSession = "end_session"
}

}

如果响应成功,它可能包含一些数据,否则,可以识别发生错误的原因(使用success属性或msg)。解析过程如下:

let model = try JSONDecoder().decode(RegularResponse<MyModel>.self, from: data)

            if model.success {
                // do something with data 
            } else {
               // handle error 
            }

一切正常,但是如果 JSON 如下所示怎么办:

{
  "success": true, 
  "name": "Jon Snow", 
  "living_place": "Nights Watch",
  //some other fields
}

在这里,我没有 data 属性。这意味着我的 RegularResponse 无法解析。那么,问题是如何处理此类情况?我的解决方案的想法很简单:始终将成功案例中的数据放入 API 的 data 字段中。通过这样做,我的 RegularResponse 将始终有效,无论 data 内部是什么。但是,它需要在服务器端进行更改。这可以在客户端修复,而不改变服务器端吗?换句话说,如何使用 Codable 在 Swift 中处理上述情况?

最佳答案

我不确定这是否是最好的解决方案,但如果您知道您的错误响应是这种形状,即:

{
  "success": false, 
  "msg": "Some error", 
  "end_session": "true",
}

然后你可以创建另一个遵循此响应的可编码结构/类。

struct ErrorResponse: Codable {
    let success: Bool
    let msg: String
    let end_session: String
}

然后当您响应 JSON 时,您可以将代码调整为:

if let successResponse = try? JSONDecoder().decode(RegularResponse<MyModel>.self, from: data) {
    //handle success
} else if let responseError = try? JSONDecoder().decode(ErrorResponse.self, from data) {
    //handle your error
}

关于ios - 如何使用 Codable 处理 JSON 响应失败的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58853397/

相关文章:

json - Angular $http.get 到本地主机,总是在浏览器中返回 404. 200

json - Angular 路由错误 path.json 的参数必须是字符串

java - 当我调用 Jenkins json api 时,如何判断构建是否正在进行?

ios - 在 Swift 中将字段添加到枚举

objective-c - 设置TextView文本属性后,屏幕没有相应更新

ios - 在 ViewController 上的 CollectionViewCell 中使用 PageControl

swift - 将变量设置为 < ("less than") 运算符作为 Swift 中的函数?

json - 使用 Swift Decodable 解析任意格式的 JSON 日期

ios - AFNetworking 与 put 和 request 主体

objective-c - 我应该用 Sencha Touch 还是 Native 编写我的应用程序?