ios 在 Firebase 中迭代快照子项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27341888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:56:34  来源:igfitidea点击:

Iterate over snapshot children in Firebase

iosswiftfirebasensenumerator

提问by dfucci

I have a Firebase resource that contains several objects and I would like to iterate over them using Swift. What I expected to work is the following (according to the Firebase documentation)
https://www.firebase.com/docs/ios-api/Classes/FDataSnapshot.html#//api/name/children

我有一个包含多个对象的 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)     
     }
 })

So it seems there is a problem with Swift iterating over the NSEnumerator object returned by Firebase.

因此,Swift 迭代 Firebase 返回的 NSEnumerator 对象似乎存在问题。

Help is really welcome.

非常欢迎帮助。

回答by vacawama

If I read the documentationright, this is what you want:

如果我正确阅读了文档,这就是您想要的:

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)     
    }
}

A better way might be:

更好的方法可能是:

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)     
    }
}

The first method requires the NSEnumeratorto return an array of all of the objects which can then be enumerated in the usual way. The second method gets the objects one at a time from the NSEnumeratorand is likely more efficient.

第一种方法要求NSEnumerator返回所有对象的数组,然后可以以通常的方式枚举这些对象。第二种方法从 中一次获取一个对象,NSEnumerator并且可能更有效。

In either case, the objects being enumerated are FIRDataSnapshotobjects, so you need the casts so that you can access the valueproperty.

在任何一种情况下,被枚举的FIRDataSnapshot对象都是对象,因此您需要强制转换以便您可以访问该value属性。



Using for-inloop:

使用for-in循环:

Since writing the original answer back in Swift 1.2 days, the language has evolved. It is now possible to use a for inloop which works directly with enumerators along with case letto assign the type:

自从用 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)     
    }
}

回答by Ketan P

I have just converted the above answer to Swift 3:

我刚刚将上述答案转换为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)
           }
})

A better way might be:

更好的方法可能是:

    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)
            }
        })

回答by Dan

This is pretty readable and works fine:

这是非常可读的并且工作正常:

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
      }
})

回答by Edward

   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
       }
   })

回答by William Hu

Firebase4.0.1

火力基地4.0.1

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

If you have multiple keys/values, and want to returnan arraywith dictionaryelements, declare an array:

如果您有多个键/值,并且想要return一个arraywithdictionary元素,请声明一个数组:

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

then change block body to this:

然后将块体更改为:

##代码##