Use Swift Decoder to pull attributes from JSON array

215 Views Asked by At

I have a JSON array created using this call:

guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [Any] else {
    print("This is not JSON!!!")
    return
}

I am trying to get elements from the JSON objects in the array to display them using the following code:

struct sWidget: Codable{
    var createdBy: String
    var createdDate: Date
    var status: String
    var widgetNumber: String
    var updatedBy: String
    var updatedDate: Date
}


do {
    let decoder = JSONDecoder()
    for (index, value) in json.enumerated() {
        let currentWidget = try decoder.decode(sWidget.self, from: json[index] as! Data)
        let currentNum = currentWidget.widgetNumber
            //print(currentNum)
        widgetNums.append(currentNum)
    }
}
catch {
    print("decoding error")
}

The code compiles but when I run it I get this error in the output:

Could not cast value of type '__NSDictionaryM' (0x1063c34f8) to 'NSData' (0x1063c1090). 2018-08-09 09:41:02.666713-0500 TruckMeterLogScanner[14259:1223764] Could not cast value of type '__NSDictionaryM' (0x1063c34f8) to 'NSData' (0x1063c1090).

I am still investigating but any tips would be helpful.

2

There are 2 best solutions below

3
On

Did you try that fetching objects like above mentioned? Because i see that you are using Codable. Fetching is very simple with that actually.

let yourObjectArray = JSONDecoder().decode([sWidget].self, data: json as! Data)

May be this line can be buggy but you can fetch them with one line.

4
On

Extending @Cemal BAYRI's answer:

JSONDecoder() throws, so make sure to either us try? or try (don't forget do-catch with try)

guard let data = content as? Data else {
   return [sWidget]()
}

let jsonDecoder = JSONDecoder()

1. try?

let yourObjectArray = try? jsonDecoder.decode([sWidget].self, data: data)

2. try

do {
  let yourObjectArray = try jsonDecoder.decode([sWidget].self, data: data)
} catch let error {
}  

Note: You would need to take care of Data and Date formatting. Below is an example for Date:

jsonDecoder.dateDecodingStrategy = .iso8601

You can also check it out here