user3591436 user3591436 - 3 months ago 24
Swift Question

Swift parse JSON formatting

I created an API that has a JSON response in the following format:

[{"name":"xxx","direct_link":"http:\/\/domain.com\/images\/xxx.png","image":"http:\/\/domain.com\/images\/xxx.png"},{"name":"yyy","direct_link":"http:\/\/domain.com\/images\/yyy.png","image":"http:\/\/domain.com\/images\/yyy.png"}]


Notice how the JSON response has no array title.

My Swift code looks like this:

do {
//converting resonse to NSDictionary
var teamJSON: NSDictionary!
teamJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary


//getting the JSON array teams from the response
let teams: NSArray = teamJSON["teams"] as! NSArray


//looping through all the json objects in the array teams
for i in 0 ..< teams.count{

//getting the data at each index
let teamId:Int = teams[i]["name"] as! String!
let teamName:String = teams[i]["direct_link"] as! String!
let teamMember:Int = teams[i]["image"] as! Int!

//displaying the data
print("name -> ", teamId)
print("direct_link -> ", teamName)
print("image -> ", teamMember)
print("===================")
print("")

}


Notice how the array is looking for a title "teams". How can I ensure the JSON is properly parsed and displays the 3 values I need for the JSON response? I'm new to app coding and have a web background, still trying to wrap my head around this.

As it stands when I try to build and run I get the following error:
fatal error unexpectedly found nil while unwrapping an optional value

Answer

Try this:

do {
    guard let teams = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray else {
        //Doesn't exist, or isn't an NSArray
        return
    }

    for team in teams {
        //getting the data at each index
        let teamId = team["name"] as! String
        let teamName = team["direct_link"] as! String
        let teamMember = team["image"] as! Int

        //displaying the data
        print("name -> ", teamId)
        print("direct_link -> ", teamName)
        print("image -> ", teamMember)
        print("===================")
        print()
    }
}
//...

Some notes:

  1. Don't cast to implicitly unwrapped optionals (e.g. String!)
  2. Don't add unnecessary type annotations
  3. Use guard let to enforce preconditions (e.g. the JSON isn't nil, and is castable to NSArray).
  4. Prefer iterating over elements of an Array (for team in teams) over iterating a range (for i in 0..<teams.count)
    • If you need only the indices, use for i in teams.indices
    • If you need the indices and elements, use for (index, team) in teams.enumerate()