swift - Acceda a la variable Firebase fuera del cierre
firebase-realtime-database uicollectionview (1)
Estoy tratando de usar Firebase para establecer el número de celdas en mi CollectionView. Intenté crear una variable local y establecerla en el mismo valor que la variable Firebase, pero cuando trato de usarla fuera de la función no funciona. También intenté configurarlo en ViewWillAppear pero no funcionó.
Configuré el título de la barra de navegación para ver el valor. Cuando se configuró en el cierre, obtuve el valor correcto, cuando escribí que fuera del cierre (después de la función firebase), daba un valor de 0.
Estoy usando swift 3
override func viewWillAppear(_ animated: Bool) {
FIRDatabase.database().reference(withPath: "data").child("numCells").observeSingleEvent(of: .value, with: { (snapshot) in
if let snapInt = snapshot.value as? Int {
// self.navigationItem.title = String(snapInt)
self.numCells = snapInt
}
}) { (error) in
print(error.localizedDescription)
}
self.navigationItem.title = String(numCells)
}
...
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return numCells
}
Firebase es asíncrono y los datos solo son válidos cuando son devueltos por Firebase dentro del cierre.
FIRDatabase.database().reference(withPath: "data").child("numCells")
.observeSingleEvent(of: .value, with: { snapshot in
if let snapInt = snapshot.value as? Int {
self.navigationItem.title = String(snapInt)
}
})
Ampliando a partir de eso, supongamos que queremos poblar una matriz para usarla como fuente de datos para una vista de tabla.
class ViewController: UIViewController {
//defined tableView or collection or some type of list
var usersArray = [String]()
var ref: FIRDatabaseReference!
func loadUsers() {
let ref = FIRDatabase.database().reference()
let usersRef = ref.child("users")
usersRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot {
let userDict = child as! [String: AnyObject]
let name = userDict["name"] as! string
self.usersArray.append[name]
}
self.myTableView.reloadData()
})
}
print("This will print BEFORE the tableView is populated")
}
Tenga en cuenta que rellenamos la matriz, que es una clase var, desde dentro del cierre y una vez que se llena esa matriz, aún dentro del cierre, actualizamos la vista de tabla.
Tenga en cuenta que la función de impresión se realizará antes de que se complete el tableView ya que el código se ejecuta de forma sincrónica y el código es más rápido que Internet, por lo que el cierre se producirá realmente después de la declaración de impresión.