Reputation: 731
I'm trying to work with the dictionary object result returned after a facebook login. The result variable looks like this
result = [ location: ["name": "Paris, France", "id": "34534999333"] ]
and my goal is to access the location name. I try this code:
if let location = result["location"]?["name"] as? String {
//do something
}
but I get the error "could not find member subscript." I see nothing wrong with the logic of my code. If result["location"] exists, then look for the index "name" in it, cast it as a string, and if successful, set the constant "location" equal to it.
I could do what I want with a longer code but I just want to learn why Swift doesn't understand the code above.
Upvotes: 1
Views: 235
Reputation: 13181
The compiler was confused. The reasoning is that the "location:" in the original looks like a dictionary assignment but the key location also looks like a variable as written. Surrounding that value with quotes to make it a distinct dictionary key will produce the desired Dictionary object. You can unwrap the place information using the following syntax.
//: Playground - noun: a place where people can play
import UIKit
let result = [ "location": ["name": "Paris, France", "id": "34534999333"] ]
if let place = result["location"]?["name"] {
//do something
print(place)
}
Option-clicking on any suspect variables after you've written the line of code would normally show a result type of << error type >> whenever the compiler is having an issue.
Upvotes: 0
Reputation: 154731
I suspect your problem is that result
is an optional type. option-click on the result
variable. If it is of type NSDictionary?
or something like [NSObject: AnyObject]?
then result
will have to be unwrapped before you can use it. I would first try:
if let location = result?["location"]?["name"] as? String {
//do something
}
If result
is AnyObject
or AnyObject?
, I would suggest taking this a step at a time:
if let dict = result as? NSDictionary {
if let location = dict["location"] as? NSDictionary {
if let name = location["name"] as? String {
// use name
}
}
}
You can compact the above into a single if:
if let name = ((result as? NSDictionary)?["location"] as? NSDictionary)?["name"] as? String {
// use name
}
Upvotes: 1
Reputation: 37053
Apart from the apparent typo (the 'location' in the assignment to result
should surely be a string literal "location"
?), the optional downcast to String
in the if let
statement is unnecessary. Swift has already inferred the type - it knows that result["location"]?["name"]
returns the type String?
.
as? String
should be producing a compiler warning, but I would not expect it to be "could not find member subscript" unless the compiler has got quite confused (which has been know at this relatively early stage in Swift's development!). Start by removing the downcast.
Upvotes: 0