У меня есть ресурс 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, итерацией по объекту NSEnumerator, возвращаемому Firebase.
Помощь действительно приветствуется.
Если я правильно прочитаю документацию, это то, что вы хотите:
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
}
})
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
a 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])
}
Ex. если users
- это имя вашей таблицы, вы сделаете это
let ref = Database.database().reference()
let usersRef = ref.child("users")
usersRef.observeSingleEvent(of: .value, with: { snapshot in
print(snapshot)
})
Результат
print(rest.value)
печатаетOptional(0)
вместо этого следует печатать целое число. Как я могу сделатьprint(rest.value)
чтобы напечатать целое число?