2017-06-21 1 views
2

Ich versuche, Daten aus Firebase zu holen und fügen Sie es als ein Objekt in einem Swift-Array, aber jedes Mal, wenn ich die Anwendung ausführen, druckt das Array leer. Wenn ich eine print Anweisung in die Beobachtung setzen, wird jeder Geldbeutel ausgedruckt, wie ich es will, aber der Geldbeutel wird nie an das Array angehängt.Füllen eines Arrays in Swift mit Firebase-Wörterbuch

var purses = [Purse]() 

override func viewDidLoad() { 
    fetchPurse(completion: {print(self.purses.count)}) 
} 

func fetchPurse(completion: @escaping() ->()){ 
    let ref = FIRDatabase.database().reference(fromURL: "https://test-database-ba3a2.firebaseio.com/") 
    let user = (FIRAuth.auth()?.currentUser?.uid)! 
    let userRef = ref.child("users").child(user).child("devices") 

    userRef.observe(.childAdded, with: { (snapshot) in 
     if let dictionary = snapshot.value as? [String: AnyObject]{ 
      let purse = Purse() 
      purse.setValuesForKeys(dictionary) 
      self.purses.append(purse) 
      completion() 
     } 
    }, withCancel: nil) 
} 
+0

Wo möchten Sie das Array drucken? Sie füllen das Array in einer asynchronen Funktion. Wenn Sie also versuchen, seine Werte außerhalb des Beendigungshandlers zu beobachten, drucken Sie höchstwahrscheinlich das Array, bevor es gefüllt wird. –

+0

Ich rufe das Array in einer anderen Funktion auf und versuche, die .count-Methode zu verwenden, um eine bestimmte Anzahl von Tabellenzellen für meine Tabellenansicht basierend darauf zu laden, wie viele Geldbörsen es gibt. –

+0

fetchPurse() sollte einen Abschluss-Handler haben und Sie sollten Ihre andere Funktion vom Complete-Handler aufrufen. –

Antwort

1

Das klingt wie ein Missverständnis, wie asynchrone Methoden funktionieren.

Wenn Sie Code verwenden:

//at this point purses is empty.. 
fetchPurse() 
print("purses count = \(purses.count)") 

Sie werden immer eine leere Geldbörsen Array sehen. Das Problem besteht darin, dass die Funktion fetchPurse() die Firebase-Funktion observe verwendet, die asynchron ist. Es fordert an, dass Firebase den Code ausführt, den Sie als Ihren with: Abschluss übergeben, wenn ein neuer Eintrag hinzugefügt wird. Die observe-Funktion gibt sofort zurück und ruft die Schließung auf, die Sie als zukünftige Uhrzeit an FireBase übergeben, wenn FireBase ein neues untergeordnetes Objekt hinzufügt.

Als Ergebnis wird auch Ihre fetchPurse() Funktion zurückgegeben, bevor das neue Geldbörse-Objekt zu Ihrem Geldbeutel-Array hinzugefügt wird.

Als @ DávidPásztor in seinem Kommentar sagte, sollten Sie fetchPurse Refactoring einen Abschluss-Handler zu nehmen, die aufgerufen wird, wenn die Geldbörsen-Array aktualisiert wird:

func fetchPurse(completion:() ->){ 
    let ref = FIRDatabase.database().reference(fromURL: "https://test-database-ba3a2.firebaseio.com/") 
    let user = (FIRAuth.auth()?.currentUser?.uid)! 
    let userRef = ref.child("users").child(user).child("devices") 

    userRef.observe(.childAdded, with: { (snapshot) in 
     if let dictionary = snapshot.value as? [String: AnyObject]{ 
      let purse = Purse() 
      purse.setValuesForKeys(dictionary) 
      self.purses.append(purse) 
      //This is the new line that calls your new completion handler 
      completion() 
     } 
    }, withCancel: nil) 
} 

Und dann würde man es so nennen:

fetchPurse(completion: { 
    print("purses count = \(purses.count)") 
} 
+0

Ich habe die Frage mit der Implementierung meines Codes aktualisiert und es zeigt immer noch ein leeres Array. Ich habe eingeschlossen, wo ich auch die fetchPurse Funktion nenne –

+0

Warte, egal, ich habe es. Vielen Dank! –

Verwandte Themen