简体   繁体   English

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

[英]How to notify or print for missing key on model class from API response in iOS Swift Codable?

I have one JSON response from API as follows, 我有一个来自API的JSON响应,如下所示,

Previous JSON Response: 以前的JSON响应:

[
  {
    "EmployeeId": 711,
    "FirstName": "Steve",
    "LastName": "Jobs"
  },
  {
    "EmployeeId": 714,
    "FirstName": "John",
    "LastName": "Doe"
  }
]

and model class for same has following code 和model的模型类有以下代码

class EmployeeModel: Codable {

    let EmployeeId: Int?
    let FirstName: String?
    let LastName: String?
}

for parsing with Swift Codable working fine Swift Codable解析工作正常

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

} catch let jsonErr {
    print(jsonErr.localizedDescription)
}

but now the 但现在

Latest JSON Response 最新的JSON响应

from API is changed and one MiddleName key is added in response see following screenshot and it is also working fine with Swift Codable code. 从API更改并添加一个MiddleName键作为响应,请参阅下面的屏幕截图,它也可以正常使用Swift Codable代码。 在此输入图像描述

But how can I get notify or print that MiddleName key is now added on JSON response from API in iOS Swift 5? 但是如何在iOS Swift 5中通过API的JSON响应添加通知或打印MiddleName键?

UPDATE TO QUESTION 更新问题

According to answer provided below by @CZ54, solution working fine but it is unable to check for another derived class missing key. 根据@ CZ54下面提供的答案,解决方案工作正常,但无法检查另一个派生类缺失键。 For example: 例如:

在此输入图像描述

// 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?
}

You can do the following: 您可以执行以下操作:

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

    }
}

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

//will print "middleName is not use yet"

You can implement the initializer and check the key if it exists as below, 您可以实现initializer并检查key是否存在,如下所示,

struct CustomCodingKey: CodingKey {

    let intValue: Int?
    let stringValue: String

    init?(stringValue: String) {
        self.intValue = Int(stringValue)
        self.stringValue = stringValue
    }

    init?(intValue: Int) {
        self.intValue = intValue
        self.stringValue = "\(intValue)"
    }
}

class EmployeeModel: Codable {

    var EmployeeId: Int?
    var FirstName: String?
    var LastName: String?

    private enum CodingKeys: String, CodingKey {
        case EmployeeId, FirstName, LastName
    }

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

        let allKeysContainer = try decoder.container(keyedBy: CustomCodingKey.self)

        self.EmployeeId = try container.decodeIfPresent(Int.self, forKey: .EmployeeId)
        self.FirstName = try container.decodeIfPresent(String.self, forKey: .FirstName)
        self.LastName = try container.decodeIfPresent(String.self, forKey: .LastName)

        let objectKeys = container.allKeys.map { $0.rawValue}
        for key in allKeysContainer.allKeys {
            if objectKeys.contains(key.stringValue) == false {
                print("Key: " + key.stringValue + " is added!")
            }
        }
    }
}

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

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