Search code examples
jsonswiftnsjsonserializationjsondecoderjsonencoder

typeMismatch in Decoding model again JSONEncoder and JSONDecoder swift 5


I am trying to update values in model and using JSON operation decode and encode. I have created model according to data. Everything is fine working but if I decode again my model it gives me typeMismatch error. I have tried but no success. Any one can help me?

Note: Original JSON Data & and Encoded Data print you can see the difference. In Encoded data "appointments": tag is missing how can I handle this and add this.

Original JSON Data:

{
  "appointments": [
    {
      "id": 15473454,
      "isProjectManual": false,
      "projectType": "i",
      "appointmentHour": "05:04",
      "projectName": "Farid Farjad",
      "warmingType": "b",
      "subTitle": "4874345 ",
      "projectDistrict": "Çay",
      "projectFirmName": "Test Firması",
      "controlHour": "",
      "date": "2019-12-26T05:04:00",
      "backgroundColorLight": "#cfd8dc",
      "backgroundColorDark": "#556f7b"
    }
  ],
  "isSuccess": true,
  "message": "İşlem Başarılı.",
  "statusCode": 1
}

Models:

struct ResponseData: Codable {

    let appointments : [Appointment]?
    let isSuccess : Bool?
    let statusCode : Int?
    let message : String?

}

struct Appointment : Codable {

    let appointmentHour : String?
    let backgroundColorDark : String?
    let backgroundColorLight : String?
    let controlHour : String?
    let date : String?
    let id : Int?
    let isProjectManual : Bool?
    let projectDistrict : String?
    let projectFirmName : String?
    let projectName : String?
    let projectType : String?
    let subTitle : String?
    let warmingType : String?
}

Encode:

var Appdata : [Appointment]? 

let jsonData = try! JSONEncoder().encode(self.Appdata)
let jsonString = String(data: jsonData, encoding: .utf8)!
print(jsonString)

Encode Prints

[
  {
    "projectName": "Farid Farjad",
    "id": 15473454,
    "subTitle": "4874345 ",
    "appointmentHour": "05:04",
    "projectDistrict": "Çay",
    "projectFirmName": "Test Firması",
    "date": "2019-12-26T05:04:00",
    "backgroundColorLight": "#cfd8dc",
    "backgroundColorDark": "#556f7b",
    "isProjectManual": false,
    "controlHour": "",
    "projectType": "i",
    "warmingType": "b"
  }
]

Decode Code

let dec = JSONDecoder()
let resp = try dec.decode(ResponseData.self, from: jsonData)
print(resp)

Decode Prints

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))

Solution

  • Your issue is that you are trying to encode

    var Appdata : [Appointment]? 
    let jsonData = try! JSONEncoder().encode(self.Appdata)
    

    Which is an array of Appointments, and then trying to decode jsonData into Dictionary

    let dec = JSONDecoder()
    let resp = try dec.decode(ResponseData.self, from: jsonData)
    

    You could either change your encoding or decoding.

    Encoding

    Change your encoding to following.

    var Appdata : ResponseData?
    

    Usage would be how you want to use.

    let resp = try dec.decode(ResponseData.self, from: jsonData)
    

    Decoding

    If you wished to use your current encoding function then you would need to decode as following.

    let resp = try dec.decode([Appointment].self, from: jsonData)