Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type 'Any' has no subscript members after updating to Swift 3

Here is my code in Swift:

currentUserFirebaseReference.observeSingleEvent(of: .value, with: { (snapshot: FIRDataSnapshot) in
        let UID = snapshot.key
        let pictureURL = snapshot.value!["pictureURL"] as! String
        let name = snapshot.value!["displayname"] as! String
        let currentUser = Person(name: name, bio: "", UID: UID, pictureURL: pictureURL)
        self.currentUserInfo = currentUser
            })

I just updated to Xcode 8 / Swift 3, which seems to have caused the following error message:

"Type 'Any' has no subscript members"

I call snapshot.value!["insert something here"] in many places in my code, I'm getting this error and I can't run my code.

The following code works:

let pic = (snapshot.value as? NSDictionary)?["pictureURL"] as? String ?? ""

However, I don't see what changed or what makes this necessary now versus how it was before.

The only thing that has changed as far as I'm aware is the syntax of the observe, but I don't understand why this caused my code to stop working.

like image 614
user6820041 Avatar asked Sep 13 '16 22:09

user6820041


2 Answers

J. Cocoe's answer is absolutely correct, but for those who need a code example this is how you do it:

instead of

let name = snapshot.value!["displayname"] as! String

try

let snapshotValue = snapshot.value as? NSDictionary
let name = snapshotValue["displayName"] as? String

The idea is that you need to cast the type of snapshot.value from Any to an NSDictionary.

Edit:

As Connor pointed out, force unwrapping snapshot.value or anything from a backend system is a bad idea due to possibly receiving unexpected information. So you change as! NSDictionary to as? NSDictionary.

like image 78
Aylii Avatar answered Oct 07 '22 11:10

Aylii


In FIRDataSnapshot, value is of type id.

In Swift 3, id is imported as Any.

In the Firebase documentation, it says value can be any of NSDictionary, NSArray, NSNumber, or NSString -- clearly, subscripting doesn't make sense on all of these, especially in Swift. If you know it's an NSDictionary in your case, then you should cast it to that.

like image 24
J. Cocoe Avatar answered Oct 07 '22 12:10

J. Cocoe