更新到Swift 3后,类型"Any"没有下标成员

use*_*041 11 ios firebase swift firebase-realtime-database

这是我在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
            })
Run Code Online (Sandbox Code Playgroud)

我刚刚更新到Xcode 8/Swift 3,这似乎导致了以下错误消息:

"输入'任意'没有下标成员"

我在我的代码中的许多地方调用snapshot.value!["插入一些东西"],我收到此错误,我无法运行我的代码.

以下代码有效:

let pic = (snapshot.value as? NSDictionary)?["pictureURL"] as? String ?? ""
Run Code Online (Sandbox Code Playgroud)

但是,我现在看不出有什么变化,或者现在是什么使它变得如此必要.

就我所知,唯一改变的是观察的语法,但我不明白为什么这导致我的代码停止工作.

Ayl*_*lii 30

J. Cocoe的答案是绝对正确的,但对于那些需要代码示例的人来说,这就是你如何做到的:

代替

let name = snapshot.value!["displayname"] as! String
Run Code Online (Sandbox Code Playgroud)

尝试

let snapshotValue = snapshot.value as? NSDictionary
let name = snapshotValue["displayName"] as? String
Run Code Online (Sandbox Code Playgroud)

这个想法是你需要将任何类型的snapshot.value从Any转换为NSDictionary.

编辑:

正如Connor指出的那样,由于可能会收到意外信息,强制从后端系统中解包snapshot.value或任何内容是一个坏主意.所以你改变了!NSDictionary为?的NSDictionary.

  • 除非你别无选择,否则请不要在Swift中使用`NSDictionary`.本机字典`[String:Any]`类型是首选,因为它提供类型信息. (3认同)

J. *_*coe 8

FIRDataSnapshot中,value属于类型id.

Swift 3中,id导入为Any.

在火力地堡文档,它说value可以是任意的NSDictionary,NSArray,NSNumber,或NSString-显然,下标无厘头对所有这些,尤其是斯威夫特.如果你知道它是NSDictionary你的情况,那么你应该把它投射到那个.