Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

Previous JSON Response:

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

and model class for same has following code

class EmployeeModel: Codable {

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

for parsing with Swift Codable working fine

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

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. enter image description here

But how can I get notify or print that MiddleName key is now added on JSON response from API in iOS Swift 5?

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. For example:

enter image description here

// 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?
}
like image 615
iAj Avatar asked Aug 14 '19 07:08

iAj


1 Answers

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"

like image 189
CZ54 Avatar answered Oct 20 '22 00:10

CZ54