可编码以使用单个模型映射不同的键值

时间:2019-02-26 10:41:17

标签: swift codable

JSON 1:

{    
 "error_code" : 100,    
 "error_message" : "Something went wrong"    
}

JSON 2

{
 "failure_code" : 100,
 "failure_message" : "Something not right here"
}

更改为以下代码以在JSON上方进行映射:

class Failure: Codable {
    var code: Int?
    var message: String?

    private enum CodingKeys: String, CodingKey {
        case code
        case message
    }
}

我们该怎么做?

2 个答案:

答案 0 :(得分:3)

这是您可以做到的一种方法:

import Cocoa
import Foundation

struct CustomError {
    var code: Int
    var message: String
}

extension CustomError : Decodable {
    private enum FirstKeys: String, CodingKey {
        case error_code, error_message
    }
    private enum SecondKeys: String, CodingKey {
        case failure_code, failure_message
    }

    init(from decoder: Decoder) throws {
        do {
            print("Case 1")
            let container = try decoder.container(keyedBy: FirstKeys.self)
            code = try container.decode(Int.self, forKey: .error_code)
            message = try container.decode(String.self, forKey: .error_message)
            print("Error with code: \(code) and message: \(message)")
        } catch {
            print("Case 2")
            let container = try decoder.container(keyedBy: SecondKeys.self)
            code = try container.decode(Int.self, forKey: .failure_code)
            message = try container.decode(String.self, forKey: .failure_message)
            print("Error with code: \(code) and message: \(message)")
        }
    }
}

let json = """
{
"failure_code": 1,
"failure_message": "test"
}
""".data(using: .utf8)!
let error =  try JSONDecoder().decode(CustomError.self, from: json)
print(error)

从我的iPhone发送

答案 1 :(得分:1)

编写一个自定义的init方法来处理案例。不需要课程。

struct Failure: Decodable {
    var code: Int
    var message: String

    private enum CodingKeys: String, CodingKey {
        case error_code, error_message
        case failure_code, failure_message
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            code = try container.decode(Int.self, forKey: .error_code)
            message = try container.decode(String.self, forKey: .error_message)
        } catch DecodingError.keyNotFound {
            code = try container.decode(Int.self, forKey: .failure_code)
            message = try container.decode(String.self, forKey: .failure_message)
        }
    }
}