Firebase Swift 3.0 Syntax Update?

2020-05-04 11:06发布

I have had an Firebase-backed iOS app that has been working well until I upgraded Xcode to Xcode 8. Now errors show up in lines such as:

let state = child.value!["STATE"] as! String // Was correct in Swift 2.3

Error in Swift 3.0: Value of type 'NSFastEnumerationIterator.Element' (aka 'Any') has no member 'value'

After Converting my code to Swift 3.0, the change made the syntax into this:

let name = (child as AnyObject).value!["NAME"] as! String

But that returns this error:

Type 'NSFastEnumerationIterator.Element' (aka 'Any') does not conform to protocol 'AnyObject'

Additionally, I am getting this error: The Type 'Any' has no subscript members when I try to access a snapshot value.

Firebase docs have not changed for Swift 3.0, so what is the issue here?

Full Code Block:

 self.firebase.child(“INFO”).observeSingleEvent(of: .value, with: { (snap: FIRDataSnapshot) in

            for child in snap.children{

                if child.hasChild("NAME") && child.hasChild("ZIP-CODE") && child.hasChild("STATE"){

                        let name = child.value!["NAME"] as! String
                          let zip = child.value!["ZIP-CODE"] as! String
                          let state = child.value!["STATE"] as! String

                }
            }

        })

Thanks for all help, it is greatly appreciated!

3条回答
甜甜的少女心
2楼-- · 2020-05-04 11:34

I am guessing you are not casting your retrieved Snapshot from an event to any type, Which might lead the Xcode confused as to what type does this Snapshot even belong to?

   FIRDatabase.database().reference().observeSingleEvent(of : .value, with : {(Snapshot) in

        if let snapDict = Snapshot.value as? [String:AnyObject]{
            for child in snapDict{

                if let name = child.value["NAME"] as? String{

                    print(name)
                }
                if let zip = child.value["ZIP-CODE"] as? String{

                    print(zip)
                }
                if let state = child.value["STATE"] as? String{

                    print(state)
                }
            }
        }
    })
查看更多
神经病院院长
3楼-- · 2020-05-04 11:38

We faced a similar issue, had to recast the children as a DataSnapshot (renamed from FIRDataSnapshot) for some reason.

So something like this:

    query.observeSingleEvent(of: .value, with: { (snapshot) in
        for childSnapshot in snapshot.children {
            if let childSnapshot = childSnapshot as? DataSnapshot,
                let data = childSnapshot.value
                // Do stuff with data
            }
        }
    })
查看更多
唯我独甜
4楼-- · 2020-05-04 11:50

Have you tried casting child.value as an NSDictionary? I've had success casting my firebase snapshots and accessing their values the following way (adapted to your situation).

self.firebase.child(“INFO”).observeSingleEvent(of: .value, with: { (snap: FIRDataSnapshot) in

        for child in snap.children{
            let childValue = child.value as? NSDictionary

            if child.hasChild("NAME") && child.hasChild("ZIP-CODE") && child.hasChild("STATE"){

                    let name = childValue!["NAME"] as! String
                      let zip = childValue!["ZIP-CODE"] as! String
                      let state = childValue!["STATE"] as! String

            }
        }

    })
查看更多
登录 后发表回答