Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDictionary in Swift:Cannot subscript a value of type 'AnyObject?' with a index of type 'Int'

Tags:

ios

swift

So I am trying to parse some data in JSON using swift. below is my code

var jsonResult:NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary

println(jsonResult)

The above code will return something like this

{
 count = 100
 subjects = (
        {
         alt = "....."
         name = "....."
         },
         {
         alt = "....."
         name = "....."
         },

         ......
         )
}

Then I try to access all the subjects with jsonResult["subjects"], so far so good But when I try to access the individual subject, for example jsonResult["subjects"][0], Xcode gives me error: Cannot subscript a value of type 'AnyObject?' with an index of type 'Int' Can someone help me with this?

like image 573
JSNoob Avatar asked Apr 30 '15 04:04

JSNoob


2 Answers

When you subscript a dictionary, as in jsonResult["subjects"], you get an Optional. You need to unwrap the Optional. Moreover, because this dictionary is arriving from JSON, Swift doesn't know what sort of thing that Optional contains: it is typed as AnyObject - that is why Swift describes the Optional as an AnyObject?. So you also tell Swift what type of object this really is - it's an array of dictionaries, and you need to tell Swift that, or you won't be able to subscript it with [0].

You can do both those things in a single move, like this:

if let array = jsonResult["subjects"] as? [[NSObject:AnyObject]] {
    let result = array[0]
    // ...
}

If you are very, very sure of your ground, you can force the unwrapping and the casting, and reduce that to a single line, like this:

let result = (jsonResult["subjects"] as! [[NSObject:AnyObject]])[0]

But I can't recommend that. There are too many ways it can go wrong.

like image 136
matt Avatar answered Sep 20 '22 13:09

matt


With Swift 2 at least, you can do with jsonResult["subject"] as! [AnyObject]

let data = try NSJSONSerialization.JSONObjectWithData(textData!, options: NSJSONReadingOptions.AllowFragments)  
let results = data["results"] as! [AnyObject]
let first = results[0]
like image 26
Jeremy Chone Avatar answered Sep 20 '22 13:09

Jeremy Chone