Глобальная переменная не наследуется от возвращенных данных Firebase (Swift) - PullRequest
0 голосов
/ 03 февраля 2019

Я пытаюсь отобразить набор координат, которые я читаю из базы данных Firebase.Я получаю координаты широты и долготы через функцию и присваиваю ее глобальной переменной, чтобы вызвать ее для отображения на моих картах.Но значения не отображаются, отображаются исходные значения (0,0, 0,0).Я распечатал свои результаты, и результат присваивается глобальным переменным, но он не наследуется, когда я хочу его отобразить.Какие обходные пути, которые я могу реализовать, или быстрые исправления?

enter image description here

    var GPSlatdata = 0.0
    var GPSlongdata = 0.0

    func getlatitude(completion: @escaping (Double)->()){
        let ref = Database.database().reference()

        ref.child("GPSData/devices/1/latitude").observeSingleEvent(of: .value) { (snapshot) in
            if let latitudefire = snapshot.value as? Double
            {
                completion(latitudefire)
            }
        }
    }

    func getlongitude(completion: @escaping (Double)->()){
        let ref = Database.database().reference()

        ref.child("GPSData/devices/1/longitude").observeSingleEvent(of: .value) { (snapshot) in
            if let longitudefire = snapshot.value as? Double
            {
                completion(longitudefire)
            }
        }

    }

    getlatitude(completion: { (latx) in
        print("Before: \(GPSlatdata)")
        print("Recieved Lat Value: \(latx)")
        GPSlatdata = GPSlatdata + latx
        print("GPSlata data is = \(GPSlatdata)")
    })

    getlongitude(completion: { (longx) in
        print("Beforelong: \(GPSlongdata)")
        print("Recieved Lat Value: \(longx)")
        GPSlongdata = GPSlongdata + longx
        print("GPSlata data is = \(GPSlongdata)")
    })


    let skateboardposition = CLLocationCoordinate2D(latitude: GPSlatdata, longitude: GPSlongdata)

    let skateboardposition = CLLocationCoordinate2D(latitude: x1, longitude: x2)

    //just added
    let skateboardAnnotation = GPSAnnotation(coordinate: skateboardposition, title: "ACES Skaters", subtitle: "Current Board location - \nLatitude: \(GPSlatdata) Longitude: \(GPSlongdata)")

    GPSMap.addAnnotation(skateboardAnnotation)
    GPSMap.setRegion(skateboardAnnotation.region, animated: true)

Обновлены изменения: Все еще не удается построить координаты.

  import UIKit
  import Foundation
  import MapKit
  import Firebase

final class GPSAnnotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?

init(coordinate: CLLocationCoordinate2D, title: String?, subtitle: String?)
{
    self.coordinate = coordinate
    self.title = title
    self.subtitle = subtitle

    super.init()
}

var region: MKCoordinateRegion{
    let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
    return MKCoordinateRegion(center: coordinate, span: span)
}
}

 extension String {
func toDouble() -> Double? {
    return NumberFormatter().number(from: self)?.doubleValue
}
}



class GPSMapViewController: UIViewController {

@IBOutlet weak var GPSMap: MKMapView!


@IBOutlet weak var latLabel: UILabel!

@IBOutlet weak var longLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    let queue = DispatchGroup()
    // Do any additional setup after loading the view.

    var GPSlatdata = 0.0
    var GPSlongdata = 0.0

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

    ref.child("GPSData/devices/1/latitude").observeSingleEvent(of: .value) { (snapshot) in
        if let latitudefire = snapshot.value as? Double
       {
        self.latLabel.text = "\(latitudefire)"
        }
    }

    ref.child("GPSData/devices/1/longitude").observeSingleEvent(of: .value) { (snapshot) in
        if let longitudefire = snapshot.value as? Double
        {

        self.longLabel.text = "\(longitudefire)"
        }
    }



    GPSMap.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)


    func getlatitude(completion: @escaping (Double)->()){
        let ref = Database.database().reference()

        ref.child("GPSData/devices/1/latitude").observeSingleEvent(of: .value) { (snapshot) in
            if let latitudefire = snapshot.value as? Double
            {
                completion(latitudefire)
            }
        }
    }

    func getlongitude(completion: @escaping (Double)->()){
        let ref = Database.database().reference()

        ref.child("GPSData/devices/1/longitude").observeSingleEvent(of: .value) { (snapshot) in
            if let longitudefire = snapshot.value as? Double
            {
                completion(longitudefire)
            }
        }

    }

    queue.enter()
    getlatitude(completion: { (latx) in
        print("Before: \(GPSlatdata)")
        print("Recieved Lat Value: \(latx)")
        GPSlatdata = GPSlatdata + latx
        print("GPSlata data is = \(GPSlatdata)")
        queue.leave()
    })

    queue.enter()
    getlongitude(completion: { (longx) in
        print("Beforelong: \(GPSlongdata)")
        print("Recieved Lat Value: \(longx)")
        GPSlongdata = GPSlongdata + longx
        print("GPSlata data is = \(GPSlongdata)")
        queue.leave()
    })


    DispatchQueue.main.async{
    let skateboardposition = CLLocationCoordinate2D(latitude: GPSlatdata, longitude: GPSlongdata)

   // let skateboardposition = CLLocationCoordinate2D(latitude: x1, longitude: x2)
        print("The skateboard position is: \(skateboardposition)")
        print("GPSlatdata is: \(GPSlatdata)")
        print("GPSlongdata is: \(GPSlongdata)")        
  let skateboardAnnotation = GPSAnnotation(coordinate: skateboardposition, title: "ACES Skaters", subtitle: "Current Board location - \nLatitude: \(GPSlatdata) Longitude: \(GPSlongdata)")

        self.GPSMap.addAnnotation(skateboardAnnotation)
        self.GPSMap.setRegion(skateboardAnnotation.region, animated: true)
    }

}
}

extension GPSMapViewController: MKMapViewDelegate{
func GPSMap(_ GPSMap: MKMapView, viewFor annotation: MKAnnotation) -> MKMarkerAnnotationView?{
    if let GPSAnnotationView = GPSMap.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) as? MKMarkerAnnotationView{
        GPSAnnotationView.animatesWhenAdded = true
        GPSAnnotationView.titleVisibility = .adaptive
        GPSAnnotationView.titleVisibility = .adaptive
    }
    return nil
}
}

Вывод: еще строим координаты (0,0, 0,0) enter image description here

enter image description here

1 Ответ

0 голосов
/ 03 февраля 2019

Вы не ожидаете завершения обработчиков завершения.Обработчики завершения не происходят автоматически - вы должны ждать получения данных.Попробуйте использовать DispatchGroup, чтобы быть уверенным в том, когда события завершены.

let queue = DispatchGroup()

for i in 0..<5 {
    //Here we add a child into a queue
    queue.enter()
    print("Entering")
    //Start some action and wait for it to finish


    //... It finishes
    queue.leave()
    print("Leaving")

}

queue.notify(queue: .main) {
    print("We are done")
}

Итак, в вашем случае

let queue = DispatchGroup()

//Start an item
queue.enter()    
getlatitude(completion: { (latx) in
    print("Before: \(GPSlatdata)")
    print("Recieved Lat Value: \(latx)")
    GPSlatdata = GPSlatdata + latx
    print("GPSlata data is = \(GPSlatdata)")

    //we found latdata so leave
    queue.leave()
})

//Start an item
queue.enter()
getlongitude(completion: { (longx) in
    print("Beforelong: \(GPSlongdata)")
    print("Recieved Lat Value: \(longx)")
    GPSlongdata = GPSlongdata + longx
    print("GPSlata data is = \(GPSlongdata)") 

    //we found longdata so leave
    queue.leave()
})


//We are done with items once they BOTH finish.
queue.notify(queue: .main) {
    let skateboardposition = CLLocationCoordinate2D(latitude: GPSlatdata, longitude: GPSlongdata)

    //just added
    let skateboardAnnotation = GPSAnnotation(coordinate: skateboardposition, title: "ACES Skaters", subtitle: "Current Board location - \nLatitude: \(GPSlatdata) Longitude: \(GPSlongdata)")

    GPSMap.addAnnotation(skateboardAnnotation)
    GPSMap.setRegion(skateboardAnnotation.region, animated: tr
}

Ссылки: https://www.raywenderlich.com/5371-grand-central-dispatch-tutorial-for-swift-4-part-2-2

Примечание. Чтобы проверить, что это так, поместите оператор печати после let skateboardposition = CLLocationCoordinate2D(latitude: GPSlatdata, longitude: GPSlongdata) и посмотрите, какие из них печатаются первыми ... новый оператор печати или те, которые находятся внутри обработчиков завершения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...