Iterate über Snapshot-Kinder in Firebase

Ich habe eine Firebase-Ressource, die mehrere Objekte enthält, und ich würde gerne mit Swift darüber iterieren. Was ich erwartet habe, ist folgendes (gemäß der Firebase-Dokumentation)
https://www.firebase.com/docs/ios-api/Classes/FDataSnapshot.html#//api/name/children

var ref = Firebase(url:MY_FIREBASE_URL) ref.observeSingleEventOfType(.Value, withBlock: { snapshot in println(snapshot.childrenCount) // I got the expected number of items for rest in snapshot.children { //ERROR: "NSEnumerator" does not have a member named "Generator" println(rest.value) } }) 

Es scheint also ein Problem zu bestehen, dass Swift über das von Firebase zurückgegebene NSEnumerator-Objekt iteriert.

Hilfe ist wirklich willkommen.

Wenn ich die Dokumentation richtig lese, ist das was du willst:

 var ref = Firebase(url: MY_FIREBASE_URL) ref.observeSingleEvent(of: .value) { snapshot in print(snapshot.childrenCount) // I got the expected number of items for rest in snapshot.children.allObjects as! [FIRDataSnapshot] { print(rest.value) } } 

Ein besserer Weg könnte sein:

 var ref = Firebase(url: MY_FIREBASE_URL) ref.observeSingleEvent(of: .value) { snapshot in print(snapshot.childrenCount) // I got the expected number of items let enumerator = snapshot.children while let rest = enumerator.nextObject() as? FIRDataSnapshot { print(rest.value) } } 

Die erste Methode erfordert, dass NSEnumerator ein Array aller Objekte NSEnumerator , die dann auf die übliche Weise aufgelistet werden können. Die zweite Methode NSEnumerator die Objekte NSEnumerator vom NSEnumerator und ist wahrscheinlich effizienter.

In beiden Fällen sind die FIRDataSnapshot Objekte FIRDataSnapshot Objekte. Sie benötigen also die FIRDataSnapshot , damit Sie auf die Eigenschaft value zugreifen können.


for-in Schleife verwenden:

Seit dem Schreiben der ursprünglichen Antwort in Swift 1.2 Tagen hat sich die Sprache weiterentwickelt. Es ist jetzt möglich, eine for in Schleife zu verwenden, die direkt mit Enumeratoren zusammenarbeitet, wobei cases den Typ zuweist:

 var ref = Firebase(url: MY_FIREBASE_URL) ref.observeSingleEvent(of: .value) { snapshot in print(snapshot.childrenCount) // I got the expected number of items for case let rest as FIRDataSnapshot in snapshot.children { print(rest.value) } } 

Ich habe gerade die obige Antwort auf Swift 3 konvertiert :

 ref = FIRDatabase.database().reference() ref.observeSingleEvent(of: .value, with: { snapshot in print(snapshot.childrenCount) // I got the expected number of items for rest in snapshot.children.allObjects as! [FIRDataSnapshot] { print(rest.value) } }) 

Ein besserer Weg könnte sein:

  ref = FIRDatabase.database().reference() ref.observeSingleEvent(of: .value, with: { snapshot in print(snapshot.childrenCount) // I got the expected number of items let enumerator = snapshot.children while let rest = enumerator.nextObject() as? FIRDataSnapshot { print(rest.value) } }) 

Das ist gut lesbar und funktioniert gut:

 var ref = Firebase(url:MY_FIREBASE_URL) ref.childByAppendingPath("some-child").observeSingleEventOfType( FEventType.Value, withBlock: { (snapshot) -> Void in for child in snapshot.children { let childSnapshot = snapshot.childSnapshotForPath(child.key) let someValue = childSnapshot.value["key"] as! String } }) 
  ref = FIRDatabase.database().reference().child("exampleUsernames") ref.observeSingleEvent(of: .value, with: { snapshot in for rest in snapshot.children.allObjects as! [FIRDataSnapshot] { guard let restDict = rest.value as? [String: Any] else { continue } let username = restDict["username"] as? String } }) 

Firebase 4.0.1

  Database.database().reference().child("key").observe(.value) { snapshot in if let datas = snapshot.children.allObjects as? [DataSnapshot] { let results = datas.flatMap({ ($0.value as! [String: Any])["xxx"] } print(results) } } 

Wenn Sie mehrere Schlüssel / Werte haben und ein array mit dictionary möchten, deklarieren Sie ein Array:

 var yourArray = [[String: Any]]() 

dann ändere den Blockkörper folgendermaßen:

  let children = snapshot.children while let rest = children.nextObject() as? DataSnapshot, let value = rest.value { self.yourArray.append(value as! [String: Any]) }