5
votes

I'm trying to take datas from a url (json file) I get this error on these lines:

var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as! NSDictionary
if (err != nil) {
    println("JSON Error \(err!.localizedDescription)")
}

Error says

Thread 6: signal SIGABIRT - Could not cast value of type '__NSArrayM' (0x518b58) to 'NSDictionary' (0x518d74).

1
Go to json.org and study the JSON syntax. It only takes 5-10 minutes to learn. Next, throw out whatever example you're cribbing from and actually write the code that matches the JSON, understanding that a JSON array ([ ]) maps to an NSArray, and a JSON object ({ }) maps to an NSDictionary.Hot Licks

1 Answers

13
votes

Whatever the JSON file data looks like, the top level object is an array. Because you passed .MutableContainers for the options: argument, the deserialization returns you a mutable array.

You are force-casting this to an NSDictionary:

as! NSDictionary

But you can't do that because it's an array, not a dictionary.

The proper thing to do depends entirely on what we're writing code for.

  • Are we always deserializing the same JSON here? Will it always have the same structure?

If we're not, we need a more dynamic approach. But if we are, this error makes it clear that you're deserializing an array, so let's change as! NSDictionary to:

as NSMutableArray

This will do several things.

Since we're bothing to grab mutable objects, this will give us mutable objects back (otherwise we shouldn't read them as mutable).

We'll actually read the right type back (an array versus a dictionary).

And by removing the !, we'll get back an optional. Good news is that this means that our code won't crash just because we got unexpected JSON.