Обработка альтернативных типов ответов API (typeMismatch) - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть 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 в декодированном объекте.

Есть здесь какие-нибудь решения?

Спасибо!

1 Ответ

2 голосов
/ 26 апреля 2020

Вы можете настроить способ декодирования ответа JSON путем переопределения / реализации init(from decoder: Decoder) throws {

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)
    }
}
...