1

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

7
  • What do you mean by How can I ensure the JSON is properly parsed? Commented Aug 18, 2016 at 18:15
  • Alex I should have been more clear. When I build and run the app I get the following error: fatal error unexpectedly found nil while unwrapping an optional value Commented Aug 18, 2016 at 18:17
  • You should read about the Swift Language Guide. It covers optionals in great detail Commented Aug 18, 2016 at 18:21
  • let teams: NSArray = teamJSON["teams"] as! NSArray This is the part that is not playing well with my JSON response, my JSON response does not contain "teams". Commented Aug 18, 2016 at 18:21
  • developer.apple.com/library/ios/documentation/Swift/Conceptual/… Commented Aug 18, 2016 at 18:21

3 Answers 3

1

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()
Sign up to request clarification or add additional context in comments.

3 Comments

Thank yu Alex, i tried the snipped but I'm getting the following error 'AnyObject' is not convertible to 'NSARRAY'; did you mean to use...
Whoops, as should be as?. I've edited my answer.
That was it, I also had to change Image to string as it wasnt a number. Thank you for both the link earlier for me to read and the snipped so I can work/break/learn from it.
1

The problem is this line:

teamJSON =  try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

because you are trying to cast a JSON array to a dictionary.

Just use

teamJSON =  try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray

And then you also won't need to do this:

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

Because teamJSON is already the array.

I think the key issue you have to be aware of is that NSJSONSerialization.JSONObjectWithData() can return either an NSDictionary OR an NSArray, depending on whether the root level data in the JSON is an array or a dictionary.

Comments

0

ISSUE:

Your NSJSONSerialization.JSONObjectWithData would return an NSArray and not NSDictionary

SOLUTION:

Update code as below:

var teamJSON =  try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray

//getting the JSON array teams from the response

let teams: NSArray = teamJSON

ALSO

Don't force cast values using !

Always cast it as optional using ?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.