处理备用 API 响应类型 (typeMismatch)

Posted

技术标签:

【中文标题】处理备用 API 响应类型 (typeMismatch)【英文标题】:Handling Alternate API Response Types (typeMismatch) 【发布时间】:2020-04-26 02:30:09 【问题描述】:

我有一个 API,通常它会返回如下响应:


    "http_status": 200,
    "error": false,
    "message": "Success.",
    "data": 
         ...
    

但是,当请求中出现错误时,响应如下所示:


    "http_status": 409,
    "error": true,
    "message": "error message here",
    "data": []

当我在这个结构上使用let decodedResponse = try JSONDecoder().decode(APIResponse.self, from: data) 时:

struct APIResponse: Codable 
    var http_status: Int
    var error: Bool
    var message: String
    var data: APIData?

有一种情况发生了错误,我得到了响应:

Expected to decode Dictionary<String, Any> but found an array instead

我希望数据在解码对象中的位置为nil

这里有什么解决方案吗?

谢谢!

【问题讨论】:

在这种情况下,我通常会诅咒 API 设计器,然后重写 init(from decoder: Decoder) throws 方法并手动解码响应 @MadProgrammer 很少看到 API 可以做到这一点?我是否应该询问后端开发人员是否可以重写它以返回一个空对象? 很遗憾,不,这并不少见 - 我一直在处理它,它激怒了我???? 【参考方案1】:

您可以通过覆盖/实现 init(from decoder: Decoder) throws 来自定义 JSON 响应的解码方式

struct APIResponse: Codable 
    enum CodingKeys: String, CodingKey 
        // I'd rename this to conform to standard Swift conventions
        // but for example...
        case http_status = "http_status"
        case error = "error"
        case message = "message"
        case data = "data"
    


    var http_status: Int
    var error: Bool
    var message: String
    var data: APIData?

    init(from decoder: Decoder) throws 
        let container = try decoder.container(keyedBy: CodingKeys.self)

        http_status = try container.decode(Int.self, forKey: .http_status)
        error = try container.decode(Bool.self, forKey: .error)
        message = try container.decode(String.self, forKey: .message)

        guard !error else  return 

        data = try container.decode(APIData.self, forKey: .data)
    

【讨论】:

以上是关于处理备用 API 响应类型 (typeMismatch)的主要内容,如果未能解决你的问题,请参考以下文章

iOS触摸事件深度解析-备用

heos显示服务器没有反应

如何使用 go 处理多个 xml API 响应结果?

错误响应上的 REST-API 不同的内容类型

在 Unmarshal 期间处理不同类型的参数

如何响应 RESTful Web 服务中的备用 URI