Mr Heelis
Mr Heelis

Reputation: 2546

Errors casting JSON object to extract data from it

I have some JSON that looks like this

[
  {
    "schema_name": "major_call",
    "schema_title": "Major Call",
    "schema_details": [
        {
            "dataname": "call_number",
            "title": "Call Number",
            "datatype": "viewtext"
        },

and some code to handle it

let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String:Any]]
for i in 0 ..< json.count{
     let schema_name: String = json[i]["schema_name"] as? String ?? "" //works fine!
     print(schema_name)
     // error: Contextual type '[String : Any]' cannot be used with array literal
     let blob: [String:Any] = json[i]["schema_details"] as? [String:Any] ?? [""] 

     for j in 0 ..< blob.count{ //this is all I want to do!
         // errror: Cannot subscript a value of type '[String : Any]' with an index of type 'Int'
         let data_name: String = blob[j]["dataname"] as? String ?? "" 
         print(schema_name +  "." + data_name)

     }
}

but it won't parse the nested object. I get an error on the lines I marked, that the type of the object is incorrect.

What types do I need to use to unpack the data?

Upvotes: 0

Views: 88

Answers (1)

vadian
vadian

Reputation: 285082

The value for key schema_details is an array, not a dictionary.

To make it clear let's use a type alias and remove the ugly C-style index based loops

typealias JSONArray = [[String:Any]]

if let json = try JSONSerialization.jsonObject(with: data) as? JSONArray {
    for schema in json {
        let schemaName = schema["schema_name"] as? String ?? ""
        print(schemaName)
        if let details = schema["schema_details"] as? JSONArray {  
            for detail in details { 
                let dataName = detail["dataname"] as? String ?? "" 
                print(schemaName +  "." + dataName)
            }
        }
    }
}

Upvotes: 3

Related Questions