swift firebase firebase-realtime-database uicollectionview uicollectionviewcell

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.