Swift Codable is expected to decrypt the dictionary <String, Any>, but will instead find the string / data
I worked with the Codable protocol
Here is my JSON file:
{"Adress": [], "Object": [{"next-date": "2017-10-30T11:00:00Z", "text-sample": "Some text", "image-path": ["photo1.png", "photo2.png"], "email": " john.doe@test.com ", "id": "27"}, {"next-date": "2017-10-30T09:00:00Z", "text-sample": "Test Test", "image-path": ["image1.png"], "email": " name.lastename@doe.com ", "id": "28"} ] } I need to focus only on the Object array, and the "image-path" array can contain lines 0, 1, or 2.
So here is my implementation:
struct Result: Codable { let Object: [MyObject] } struct MyObject: Codable { let date: String let text: String let image: [String] let email: String let id: String enum CodingKeys: String, CodingKey { case date = "next-date" case text = "text-sample" case image = "image-path" case email = "email" case id = "id" } init() { self.date = "" self.text = "" self.image = [] self.email = "" self.id = "" } } I call this from my service class after requesting and receiving JSON data in this way:
if let data = response.data { let decoder = JSONDecoder() let result = try! decoder.decode(Result, from: data) dump(result.Object) } Everything works except [String] for the image property.
I tried different things, like this one:
struct Result: Codable { let Object: [MyObject] } struct MyObject: Codable { struct Image: Codable { let imgName: String } let date: String let text: String let image: [Image] let email: String let id: String enum CodingKeys: String, CodingKey { case date = "next-date" case text = "text-sample" case image = "image-path" case email = "email" case id = "id" } init() { self.date = "" self.text = "" self.image = [] self.email = "" self.id = "" } } But it can not compile, or I get the error "Expected decoding ...".
How do I handle the nil / no data script?
I made a small change to your MyObject struct , i.e.,
1. All properties are marked as optionals
2. Removed init() (I donβt think there is an init() requirement here.)
3. Use Result.self instead of Result in the decoder.decode(...) method
struct MyObject: Codable { let date: String? let text: String? let image: [String]? let email: String? let id: String? enum CodingKeys: String, CodingKey { case date = "next-date" case text = "text-sample" case image = "image-path" case email = "email" case id = "id" } } To check the above, I used the code below and it works fine.
let jsonString = """ {"Adress": [], "Object": [{"next-date": "2017-10-30T11:00:00Z", "text-sample": "Some text", "image-path": ["photo1.png", "photo2.png"], "email": " john.doe@test.com ", "id": "27"}, {"next-date": "2017-10-30T09:00:00Z", "text-sample": "Test Test", "image-path": ["image1.png"], "email": " name.lastename@doe.com ", "id": "28"} ] } """ if let data = jsonString.data(using: .utf8) { let decoder = JSONDecoder() let result = try? decoder.decode(Result.self, from: data) //Use Result.self here print(result) } This is the result value that I get:
