[英]Iterate over snapshot children in Firebase
我有一个包含多个对象的 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)
}
})
因此,Swift 迭代 Firebase 返回的 NSEnumerator 对象似乎存在问题。
非常欢迎帮助。
如果我正确阅读了文档,这就是您想要的:
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
返回所有对象的数组,然后可以以通常的方式枚举这些对象。 第二种方法从NSEnumerator
一次获取一个对象,并且可能更有效。
在任何一种情况下,被枚举的对象都是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
}
})
火力基地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)
}
}
火力基地7.3.0
Database.database().reference().child("key").observe(.value) { snapshot in
if let datas = snapshot.children.allObjects as? [DataSnapshot] {
let results = datas.compactMap({
($0.value)
})
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])
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.