2017-06-12 4 views
0

Also hatte ich Probleme, die vorher mit 'beobachten' von Firebase arbeiteten, und ich erkannte, dass ich die Variablenwerte aus dem Code-Block, der asynchron arbeitete, nicht bringen konnte. Ein Benutzer hat mir gesagt, Abschluss-Handler zu verwenden, um dieses Problem zu beheben, und sein Beispiel war:Wie schreibe ich einen Abschlusshandler für Firebase-Daten?

func mapRegion(completion: (MKCoordinateRegion)->()) { 

databaseHandle = databaseRef.child("RunList").child(runName).observe(.value, with: { (snapshot) in 

    let runData = snapshot.value as? [String: AnyObject] 
    self.minLat = runData?["startLat"] as? Double 
    self.minLng = runData?["startLong"] as? Double 
    self.maxLat = runData?["endLat"] as? Double 
    self.maxLng = runData?["endLong"] as? Double 
    print("testing") 
    print(self.minLat!) 
    print(self.maxLng!) 

    let region = MKCoordinateRegion(
     center: CLLocationCoordinate2D(latitude: (self.minLat! + self.maxLat!)/2, 
             longitude: (self.minLng! + self.maxLng!)/2), 
     span: MKCoordinateSpan(latitudeDelta: (self.maxLat! - self.minLat!)*1.1, 
           longitudeDelta: (self.maxLng! - self.minLng!)*1.1)) 
    completion(region) 

}) 
} 

und den Code zu verwenden:

mapRegion() { region in 
mapView.region = region 
// do other things with the region 
} 

Also habe ich versucht, dies für eine andere Methode zu erstellen, die ich brauche eine Reihe von Objekttyp RunDetail zurückzukehren:

func loadRuns(completion: ([RunDetail]) ->()) { 

    // we need name, distance, time and user 
    databaseHandle = databaseRef.child("RunList").observe(.value, with: { (snapshot) in 

     self.count = Int(snapshot.childrenCount) 
     print(self.count!) 

     // more stuff happening here to add data into an object called RunDetail from firebase 
     // add RunDetail objects into array called 'run' 

    }) 

    completion(runs) 

} 

ich bin nicht sicher, ob ich das richtig da oben bin Einstellung ^.

Ich bekomme immer noch nicht den Kopf um den Abschluss-Handler zu arbeiten (ich verstehe wirklich nicht, wie man es einrichtet). Kann mir bitte jemand helfen und mich wissen lassen, ob ich das richtig aufstelle? Vielen Dank.

+0

ich mein Versuch, ein bisschen fixiert auf, vergaß es im Bearbeitungs Grund hinzuzufügen. – Mr10k

Antwort

3

Sie müssen die completion(region) in das Innere des Firebase Abschluss Block zu bewegen, und fügen Sie @escaping nach completion:.

Auch sollten Sie nicht unwrap Optionen erzwingen. Es ist leicht genug zu überprüfen, dass sie nicht nil sind und dies verhindert, dass die App abstürzt.

func mapRegion(completion: @escaping (MKCoordinateRegion?) -> Void) { 

    let ref = Database.database().reference() 

    ref.child("RunList").child(runName).observe(.value, with: { (snapshot) in 

     guard 

      let runData = snapshot.value as? Dictionary<String,Double>, 

      let minLat = runData["startLat"], 

      let minLng = runData["startLong"], 

      let maxLat = runData["endLat"], 

      let maxLng = runData["endLong"] 

     else { 

      print("Error! - Incomplete Data") 

      completion(nil) 

      return 
     } 

     var region = MKCoordinateRegion() 

     region.center = CLLocationCoordinate2D(latitude: (minLat + maxLat)/2, longitude: (minLng + maxLng)/2) 

     region.span = MKCoordinateSpanMake((maxLat - minLat) * 1.1, (maxLng - minLng) * 1.1) 

     completion(region) 
    }) 
} 

Dann aktualisieren Sie Ihren Code zu diesem.

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    mapRegion { (region) in 

     if let region = region { 

      self.mapView.setRegion(region, animated: true) 
     } 
    } 
} 

Für Ihre loadRuns

func loadRuns(completion: @escaping (Array<RunDetail>) -> Void) { 

    let ref = Database.database().reference() 

    ref.child("RunList").observe(.value, with: { (snapshot) in 

     var runs = Array<RunDetail>() 

     // Populate runs array. 

     completion(runs) // This line needs to be inside this closure. 
    }) 
} 
+0

Danke für die Antwort, aber ich verstand, wie das Beispiel funktionierte, da es eine Antwort von einem anderen Benutzer war. In meiner Frage habe ich ein Beispiel für meinen eigenen Versuch gegeben, ein Array zurückzugeben, und da bin ich verwirrt, wenn ich den Completion-Block richtig aufstelle. Daher hilft mir diese Antwort nicht sehr. – Mr10k

+0

Schauen Sie sich meine bearbeitete Antwort an. –

+0

Okay, das macht Sinn, und ich würde 'runs' genauso verwenden wie das Beispiel für 'region' in dem anderen Beispiel. – Mr10k

Verwandte Themen