不能调用非函数类型的值'Any?!' : - Firebase,Swift3

时间:2016-09-17 20:23:00

标签: ios swift firebase firebase-realtime-database

这是我的代码之前转移到Swift 3:

ref.observeEventType(.ChildAdded, withBlock: { snapshot in
            let currentData = snapshot.value!.objectForKey("Dogs")
            if currentData != nil {
            let mylat = (currentData!["latitude"])! as! [String]
            let mylat2 = Double((mylat[0]))
            let mylon = (currentData!["longitude"])! as! [String]
            let mylon2 = Double((mylon[0]))
            let userid = (currentData!["User"])! as! [String]
            let userid2 = userid[0]
            let otherloc = CLLocation(latitude: mylat2!, longitude: mylon2!)
            self.distanceBetweenTwoLocations(self.currentLocation, destination: otherloc, userid: userid2)
            }
        })

这是我的代码 之后转移到Swift 3:

ref.observe(.childAdded, with: { snapshot in
            let currentData = (snapshot.value! as AnyObject).object("Dogs")
            if currentData != nil {
                let mylat = (currentData!["latitude"])! as! [String]
                let mylat2 = Double((mylat[0]))
                let mylon = (currentData!["longitude"])! as! [String]
                let mylon2 = Double((mylon[0]))
                let userid = (currentData!["User"])! as! [String]
                let userid2 = userid[0]
                let otherloc = CLLocation(latitude: mylat2!, longitude: mylon2!)
                self.distanceBetweenTwoLocations(self.currentLocation, destination: otherloc, userid: userid2)
            }
        })

然后我在第二行收到错误:

  

无法调用非功能类型的值'Any?!'

我唯一尝试的是将第二行更改为此代码:

snapshot.value as! [String:AnyObject]

但它不对,没有包含“Dogs”,并且它向我发出警告,distanceBetweenTwoLocations代码从未使用过。

3 个答案:

答案 0 :(得分:6)

看到的问题是,当您实例化并初始化变量时,您会告诉它,对于名为value的对象,它将收到的值为 Dogs 存在于此快照中,其类型为AnyObject

snapshot.value 的字典类型为[String:AnyObject]NSDictionary ..

您检索的Dogs节点类型为Dictionary或Array。

基本上你应该避免在AnyObject

类型的变量中存储一个值

试试这个: -

      FIRDatabase.database().reference().child("Posts").child("post1").observe(.childAdded, with: { snapshot in
        if let currentData = (snapshot.value! as! NSDictionary).object(forKey: "Dogs") as? [String:AnyObject]{

            let mylat = (currentData["latitude"])! as! [String]
            let mylat2 = Double((mylat[0]))
            let mylon = (currentData["longitude"])! as! [String]
            let mylon2 = Double((mylon[0]))
            let userid = (currentData["User"])! as! [String]
            let userid2 = userid[0]
            let otherloc = CLLocation(latitude: mylat2!, longitude: mylon2!)
            self.distanceBetweenTwoLocations(self.currentLocation, destination: otherloc, userid: userid2)
        }
    })

PS: - 看到您的JSON结构,您可能希望将其转换为字典而不是数组

答案 1 :(得分:1)

在Swift 3中,AnyObject已更改为Any,这实际上可以是任何内容。 特别是在使用键和索引下标时,现在需要告诉编译器实际的类型。

解决方案是将snapshot.value转换为Swift字典类型[String:Any]。可选绑定安全地展开值

if let snapshotValue = snapshot.value as? [String:Any], 
   let currentData = snapshotValue["Dogs"] as? [String:Any] {

     let mylat = currentData["latitude"] as! [String]
     ...

您使用的感叹号太多了。在latitude"]之前不需要as!之后的标记,并始终使用if let而不是检查nil

答案 2 :(得分:1)

我还有一个代码,允许您访问子节点的值。我希望这会对你有所帮助:

if let snapDict = snapShot.value as? [String:AnyObject] {

            for child in snapDict{

                if let name = child.value as? [String:AnyObject]{

                    var _name = name["locationName"]
                    print(_name)
                }

            }

        }

祝你好运, Nazar Medeiros