Chris Schlitt Chris Schlitt - 2 months ago 15
JSON Question

Swift 3 - Pass Dictionary inside Array from JSON to Another Method

I have the following JSON:

{
"stores":2,
"store_data":[
{
"store_id":1,
"store_name":"Target"
"store_color":"000000"
},
{
"store_id":2,
"store_name":"Walmart"
"store_color":"FFFFFF"
}
]
}


And I am collecting it (within a function) the following way (safeguards removed for simplicity):

let task = URLSession.shared.dataTask(with: baseURL) { (data, response, error) in
if let tmpRawData: NSDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary {
process(rawData: tmpRawData)
}
}


And sending it to the helper process function defined as:

func process(rawData: NSDictionary) -> Bool {
if let storeDataArray = rawData["store_data"] {
// Here I want to loop through the store_data array
}
}


And I am having some trouble looping through the array in the function above. Initially, I had tried:

for store: Dictionary<String, String> in storeDataArray {
// Do things with store["store_id"] here
}


But I am new to swift and am having trouble deciphering between NSArray, Array, Dictionary, NSDictionary, etc. I'm working in Swift 3. Any help is much appreciated!

Answer

First of all, don't annotate types that much. The compiler will tell you if it needs an explicit annotation

Second of all it's convenient to declare a type alias for a JSON dictionary

typealias JSONObject = [String:Any]

This is the task, tmpRawData is a dictionary – represented by {} in the JSON.

let task = URLSession.shared.dataTask(with: baseURL) { (data, response, error) in
  if let tmpRawData = try JSONSerialization.jsonObject(with: data, options: []) as! JSONObject {
    process(rawData: tmpRawData)
  }
}

and the process function, the type alias makes everything more readable.
The value of rawData is an array of dictionaries – represented by [] in the JSON.

func process(rawData: JSONObject) -> Bool {
  if let storeDataArray = rawData["store_data"]  as? [JSONObject] {
    for store in storeDataArray {
      let storeID = store["store_id"] as! Int
      let storeName = store["store_name"] as! String
      let storeColor = store["store_color"] as! String
     print(storeID, storeName, storeColor)
    }
  }
}

I have no idea why all tutorials suggests the mutableContainers option. You don't need it at all in Swift when using native collection types.

Comments