2016-05-08 14 views
0

Ich versuche, eine Funktion zu schreiben, die ein Array aller meiner Arbeiter zurückkehren, aber es zurückkehrt, bevor die Daten von FeuerbasisFertig asynchrone Aufgabe in Firebase mit Swift

hier Abrufen ist mein Code:

func getWorkersList() -> ([Worker]) 
{ 
    let workersInfoRef = ref.childByAppendingPath("countries/\(userCountry)/cities/\(userCity)/workers/\(workFieldToRecieve)/") 

    var workerList = [Worker]() 
     workersInfoRef.queryOrderedByChild("name").observeSingleEventOfType(.Value, withBlock: { (snapshot) in 

     print(snapshot.childrenCount) 
     for rest in snapshot.children.allObjects as! [FDataSnapshot]{ 

      let workerInfo = Worker(uid: rest.value["uid"] as! String, name: rest.value["name"] as! String, city: rest.value["city"] as! String, profession: rest.value["profession"] as! String, phone: rest.value["phone"] as! String, email: rest.value["email"] as! String, country: rest.value["country"] as! String) 
      workerList.append(workerInfo) 

     } 
     }) { (error) in 
      print(error.description) 
    } 

    print(workerList.count) 
    return workerList 

} 

Antwort

2

Dies ist nicht getestet ... ich codiert es gerade auf der Fliege bis Sie die allgemeine Idee

fügen Sie einen Abschluss Block/Rückruf an Ihre Funktion zu geben ...

func getWorkersList(callback: ((data:[Worker]) ->Void)) { 
    let workersInfoRef = ref.childByAppendingPath("countries/\(userCountry)/cities/\(userCity)/workers/\(workFieldToRecieve)/") 

    var workerList = [Worker]() 
    workersInfoRef.queryOrderedByChild("name") 
     .observeSingleEventOfType(.Value, withBlock: { (snapshot) in 

     print(snapshot.childrenCount) 
     for rest in snapshot.children.allObjects as! [FDataSnapshot]{ 

      let workerInfo = Worker(uid: rest.value["uid"] as! String, name: rest.value["name"] as! String, city: rest.value["city"] as! String, profession: rest.value["profession"] as! String, phone: rest.value["phone"] as! String, email: rest.value["email"] as! String, country: rest.value["country"] as! String) 
      workerList.append(workerInfo) 

     } 
     print(workerList.count) 
     callback(workerList) 

    }) { (error) in print(error.description) } 
} 

Pass im Abschluss Block ..

getWorkersList(callback: { (data:[Worker]) -> Void in 
    print(data) 
}) 
+0

Was ist der Zweck der Rückrufe? Ich denke, das kann Probleme bei asynchronen Callbacks bei einem asynchronen Firebase-Aufruf verursachen. (??) – Jay

+1

Der Callback gibt das Array an den Aufrufer zurück ... Sie geben das Array zurück, bevor der withBlock abgeschlossen ist. –

+0

Ich war nicht der OP, aber Ihre Antwort ist sicherlich eine Möglichkeit, es zu tun. Es braucht ein paar kleinere Verbesserungen, aber es ist ziemlich pünktlich. – Jay

0

Der Code in Ihrer Frage zu einem grundlegenden Problem nicht durch Arbeit: Firebase asynchron ist und nicht wie ein aufgerufen werden kann Werte zurückgeben Funktion.

Firebase-Daten sind nur möglich, wenn (innerhalb) der Block, der sie abgerufen hat, abgeschlossen ist.

Der App-Code läuft viel schneller als das Internet. Wenn Sie Firebase anweisen, Daten abzurufen und dann mit diesen Daten außerhalb des Blocks zu arbeiten (z. B. mit return workerList), wird die Rückmeldung ausgelöst, bevor die Firebase-Daten bereit sind und du wirst nil manchmal zurückgeben, vielleicht immer.

Also was machst du? Sie codieren asynchron.

Sagen Sie zum Beispiel, Sie haben eine Tabelle, die eine Liste von Arbeitern darstellt. Hier ist ein konzeptioneller Fluss

tell firebase to get data withBlock { 
    iterate over returned snapshot data to populate an array 
    when done, tableView.reloadData 
} 

Der Schlüssel ist die asynchrone Natur von Firebase zu nutzen und Code schreiben, mit Firebase arbeitet.