Tag: Codable

  • Handling Swift JSONDecoder typeMismatch error while using Codable protocol

    If you have a problematic JSON, which can contain number or string for some keys, you can decode object without that property and manually set that property after decoding.

    For example, I have a Vehicle class inside HistoryItem. In Vehicle model_year can be empty String or non empty Int. Here I am decoding modelYear manually using NSDictionary and trying to get Int. Swift 4 cannot do it automatically.

        do {
            // Decoding HistoryItem from JSON
            let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
            let decoder = JSONDecoder()
            let historyItem = try decoder.decode(HistoryItem.self, from: jsonData)
            if let modelYear = (dict as NSDictionary).value(forKeyPath: "vehicle.model_year") as? Int {
                historyItem.vehicle?.modelYear = modelYear
            }
            
            // Saving HistoryItem to Realm
            let realm = try! Realm()
            try! realm.write {
                realm.add(historyItem, update: true)
            }
            
        } catch {
            print(error.localizedDescription)
        }
    

    This is my Vehicle class that is contained inside HistoryItem:

        class Vehicle: Object, Codable {
            @objc dynamic var VIN: String = ""
            @objc dynamic var make: String?
            @objc dynamic var modelName: String?
            @objc dynamic var recallCount: Int = 0
            @objc dynamic var modelYear: Int = 0
            
            override static func primaryKey() -> String? {
                return "VIN"
            }
            
            private enum CodingKeys: String, CodingKey {
                case VIN = "vin"
                case make
                case modelName = "model_name"
                case recallCount = "recall_count"
            }
        }
    

    As you see, there is no model_year key in CodingKeys.