简体   繁体   English

如何使用 Codable 处理 JSON 响应的失败案例?

[英]How to handle failure cases of JSON response using Codable?

I have some JSON response, that I take from a server.我有一些来自服务器的 JSON 响应。 In success case, it might be like:在成功的情况下,它可能是这样的:

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

If all server responses would be successful, it would be really easy to parse that JSON.如果所有服务器响应都成功,那么解析 JSON 将非常容易。 But we have also failure cases like:但我们也有失败案例,例如:

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

That means we need to handle two cases.这意味着我们需要处理两种情况。 As you noticed, attributes like success, msg may occur in any response.正如您所注意到的,诸如success, msg类的属性可能出现在任何响应中。 In order to handle that, I created following struct:为了处理这个问题,我创建了以下结构:

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"
}

}

It may contain some data if response is successfull or otherwise, it is possible to identify why the error occurred(using success attribute or msg ).如果响应成功或不成功,它可能包含一些数据,可以确定错误发生的原因(使用success属性或msg )。 Parsing process would go like following:解析过程将 go 如下所示:

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

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

Everything works fine, but what if following JSON comes as following:一切正常,但如果遵循 JSON 如下:

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

Here, I don't have data attribute.在这里,我没有data属性。 It means, my RegularResponse cannot be parsed.这意味着,我的RegularResponse无法解析。 So, the question is how to handle these kind of situations?那么,问题是如何处理这些情况? My idea for solution is simple: always put data in success cases into data field on my API.我的解决方案很简单:始终将成功案例中的数据放入我的 API 的data字段中。 By doing so, my RegularResponse will always work, no matter what is inside data .通过这样做,我的RegularResponse将始终有效,无论内部data是什么。 But, it requires changes on a server side.但是,它需要在服务器端进行更改。 Can this be fixed in a client side, not changing a server side?这可以在客户端修复,而不是更改服务器端吗? In other words, how to handle above situation in Swift using Codable?换句话说,如何使用 Codable 处理 Swift 中的上述情况?

I'm not sure if this is the best solution but if you know that your error response is in that shape, ie:我不确定这是否是最好的解决方案,但如果您知道您的错误响应是这种形状,即:

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

then you could make another Codable struct/class that follows this response.那么你可以在这个响应之后创建另一个 Codable 结构/类。

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

and then when you are responding to your JSON you could adjust your code to:然后当您响应您的 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM