Невозможно сравнить значения широты / долготы Firebase в didUpdateLocations - PullRequest
0 голосов
/ 07 апреля 2019

Я имею дело с простой проблемой, связанной с получением данных из Firebase и использованием этих данных в другом месте моего кода.Ниже у меня есть функция, которая извлекает широту и долготу местоположения и сохраняет их в двух переменных locationLat и locationLong, определенных и первоначально установленных в 0.0.Я вызываю эту функцию в viewDidLoad.

Две переменные, которые содержат широту и долготу, затем доступны в didUpdateLocations, чтобы сравнить местоположение пользователя с широтой и долготой значений, которые были получены из Firebase.

Моя проблема: условие if в didUpdateLocations не будет работать все время, а когда оно не работает, широта и долгота выводят 0.0 или nil и не выполняет оператор if.

Я понимаю, что applySingleEvent по своей природе асинхронный, но я не уверен, как правильно использовать данные Firebase в моем коде, когда я получаю их, особенно в функции делегата didUpdateLocations.Любой совет был бы хорош.

Ниже приведены две функции, связанные с этой проблемой.Первая - моя функция, которая получает широту и долготу из Firebase.Вторая функция - это моя didUpdateLocations функция, в которой возникает моя ошибка.

func getLocationCoordinates() {
        let ref = Database.database().reference().child("map").child(self.titleString)
        ref.observeSingleEvent(of: .value) { (snapshot) in
                let nameSnapshots = snapshot.childSnapshot(forPath: "title")
                let val = nameSnapshots.value as! String
                if self.locationName.text == val {
                    let latitude = snapshot.childSnapshot(forPath: "latitude")
                    let longitude = snapshot.childSnapshot(forPath: "longitude")
                    let latValue = latitude.value as! CLLocationDegrees
                    let lonValue = longitude.value as! CLLocationDegrees
                    self.locationLat = latValue
                    self.locationLong = lonValue
                }
            }
        }

, а вот функция didUpdateLocations

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        manager.desiredAccuracy = kCLLocationAccuracyBest
        let userLocation :CLLocation = locations[0] as CLLocation
        let locationAddress: CLLocation = CLLocation(latitude: locationLat, longitude: locationLong)
        print("loc latitude = \(locationAddress.coordinate.latitude)")
        print("loc longitude = \(locationAddress.coordinate.longitude)")
        let distanceFrom : CLLocationDistance = userLocation.distance(from: locationAddress)
        if 300 >= distanceFrom {
            checkInOutlet.isEnabled = true
            print("we are here")
        } else {
            checkInOutlet.isEnabled = false
            print("not here yet")
        }
        locationManager.stopUpdatingLocation()
    }

1 Ответ

2 голосов
/ 07 апреля 2019

Поскольку ваши getLocationCoordinates и didUpdateLocations являются async вызовами, вам нужно дождаться, пока getLocationCoordinates выдаст результат с сервера firebase, и используйте возвращаемое значение в методе didUpdateLocations.

для этого выможно использовать completion закрытие.Проверьте приведенный ниже пример кода:

func getLocationCoordinates(completion: @escaping (_ lat: CLLocationDegrees, _ lon: CLLocationDegrees)->()) {

    let ref = Database.database().reference().child("map").child(self.titleString)
    ref.observeSingleEvent(of: .value) { (snapshot) in
        let nameSnapshots = snapshot.childSnapshot(forPath: "title")
        let val = nameSnapshots.value as! String
        if self.locationName.text == val {
            let latitude = snapshot.childSnapshot(forPath: "latitude")
            let longitude = snapshot.childSnapshot(forPath: "longitude")
            let latValue = latitude.value as! CLLocationDegrees
            let lonValue = longitude.value as! CLLocationDegrees
            self.locationLat = latValue
            self.locationLong = lonValue

            completion(latValue, lonValue) //this will return your data
        }
    }
}

Я изменил ваш getLocationCoordinates с помощью completion обратного вызова и completion будет вызывать, когда он получит данные с сервера Firebase и вернет значения lat и lon изэтот вызов.

Теперь вам нужно использовать это в вашем didUpdateLocations методе, как показано ниже:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    manager.desiredAccuracy = kCLLocationAccuracyBest
    let userLocation :CLLocation = locations[0] as CLLocation

    //call your method like this
    getLocationCoordinates { (lat, lon) -> () in

        //use lat and lon which returned by above method
        let locationAddress: CLLocation = CLLocation(latitude: lat, longitude: lon)
        print("loc latitude = \(locationAddress.coordinate.latitude)")
        print("loc longitude = \(locationAddress.coordinate.longitude)")
        let distanceFrom : CLLocationDistance = userLocation.distance(from: locationAddress)
        if 300 >= distanceFrom {
            self.checkInOutlet.isEnabled = true
            print("we are here")
        } else {
            self.checkInOutlet.isEnabled = false
            print("not here yet")
        }
        self.locationManager.stopUpdatingLocation()
    }
}
...