複数のオブジェクトを含むFirebaseリソースがあり、Swiftを使用してそれらを反復処理したいと思います。私が働くことを期待していたのは次のとおりです(Firebaseのドキュメントによる)
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)
}
})
そのため、Firebaseから返されたNSEnumeratorオブジェクトを繰り返し処理するSwift=に問題があるようです。
ヘルプは大歓迎です。
documentation rightを読んだ場合、これはあなたが望むものです:
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)
}
}
より良い方法は次のとおりです。
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)
}
}
最初のメソッドは、すべてのオブジェクトの配列を返すためにNSEnumerator
を必要とし、その後、通常の方法で列挙できます。 2番目のメソッドは、NSEnumerator
から一度に1つずつオブジェクトを取得し、おそらくより効率的です。
どちらの場合も、列挙されるオブジェクトはFIRDataSnapshot
オブジェクトです。したがって、value
プロパティにアクセスするにはキャストが必要です。
for-in
ループの使用:
元の回答をSwift 1.2日で書き戻したため、言語は進化しました。for in
と共に列挙子で直接動作するcase let
ループを使用できるようになりました。タイプを割り当てるには:
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)
}
}
上記の答えをSwift 3:に変換しました
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)
}
})
より良い方法は次のとおりです。
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)
}
})
これは非常に読みやすく、正常に機能します。
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)
}
}
複数のキー/値があり、return
要素とarray
およびdictionary
を使用する場合は、配列を宣言します。
var yourArray = [[String: Any]]()
次に、ブロック本体をこれに変更します。
let children = snapshot.children
while let rest = children.nextObject() as? DataSnapshot, let value = rest.value {
self.yourArray.append(value as! [String: Any])
}