如何从iOS Swift Codable的API响应中通知或打印模型类上缺少的键?

iAj*_*iAj 6 json ios swift codable decodable

我从API收到一个JSON响应,如下所示:

先前的JSON响应:

[
  {
    "EmployeeId": 711,
    "FirstName": "Steve",
    "LastName": "Jobs"
  },
  {
    "EmployeeId": 714,
    "FirstName": "John",
    "LastName": "Doe"
  }
]
Run Code Online (Sandbox Code Playgroud)

和相同的模型类具有以下代码

class EmployeeModel: Codable {

    let EmployeeId: Int?
    let FirstName: String?
    let LastName: String?
}
Run Code Online (Sandbox Code Playgroud)

Swift Codable解析工作正常

do {
    let decodedResponse = try JSONDecoder().decode([EmployeeModel].self, from: response.rawData())
    print(decodedResponse)

} catch let jsonErr {
    print(jsonErr.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)

但是现在

最新的JSON响应

从API更改,并添加了一个MiddleName键作为响应,请参见以下屏幕截图,并且它与Swift Codable代码也可以正常工作。 在此处输入图片说明

但是,如何从iOS Swift 5的API的JSON响应中获得通知或打印MiddleName密钥的信息呢?

更新问题

根据@ CZ54在下面提供的答案,解决方案可以正常工作,但无法检查是否缺少另一个派生类。例如:

在此处输入图片说明

// MARK:- LoginModel
class LoginModel: Codable {

    let token: String?
    let currentUser: CurrentUser?
}

// MARK:- CurrentUser
class CurrentUser: Codable {

    let UserName: String?
    let EmployeeId: Int?
    let EmployeeName: String?
    let CompanyName: String?
}
Run Code Online (Sandbox Code Playgroud)

CZ5*_*Z54 8

您可以执行以下操作:

let json = """
    {
        "name" : "Jobs",
        "middleName" : "Bob"
    }
"""


class User: Decodable {
    let name: String
}
extension JSONDecoder {
    func decodeAndCheck<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable  {
       let result = try self.decode(type, from: data)

        if let json = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions()) as? [String: Any] {
            let mirror = Mirror(reflecting: result)
            let jsonKeys = json.map { return $0.0 }
            let objectKeys = mirror.children.enumerated().map { $0.element.label }

            jsonKeys.forEach { (jsonKey) in
                if !objectKeys.contains(jsonKey) {
                    print("\(jsonKey) is not used yet")
                }
            }
        }
        return result

    }
}
Run Code Online (Sandbox Code Playgroud)

try JSONDecoder().decodeAndCheck(User.self, from: json.data(using: .utf8)!)

//will print "middleName is not use yet"

  • 很好的解决方案。但是如果检查失败以及JSONSerialization错误,则应该抛出DecodingError。 (4认同)