Не удается обновить ярлык после получения местоположения - PullRequest
1 голос
/ 21 июня 2019

У меня есть простая кнопка, когда я нажимаю кнопку, я звоню в другой класс, мой класс Location, чтобы узнать текущее местоположение пользователя. После получения местоположения, я хочу обновить текст метки, я должен показать местоположение.

Это мой класс местоположения:

class LocationManager: NSObject, CLLocationManagerDelegate {

var locationManager: CLLocationManager!
var geoCoder = CLGeocoder()

var userAddress: String?

override init() {
    super.init()
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.activityType = .other
    locationManager.requestWhenInUseAuthorization()
}

func getUserLocation(completion: @escaping(_ result: String) -> ()){
    if CLLocationManager.locationServicesEnabled(){
        locationManager.requestLocation()
    }
    guard let myResult = self.userAddress else { return }
    completion(myResult)

}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
    let userLocation: CLLocation = locations[0] as CLLocation
    geoCoder.reverseGeocodeLocation(userLocation) { (placemarks, err) in
        if let place = placemarks?.last{
            self.userAddress = place.name!
        }
    }
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print(error)
}
}

и вот где я вызываю метод и обновляю метку:

func handleEnter() {
    mView.inLabel.isHidden = false
    location.getUserLocation { (theAddress) in
        print(theAddress)
        self.mView.inLabel.text = "\(theAddress)"
    }
}

Моя проблема в том, что когда я нажимаю кнопку (и запускаю handleEnter ()), ничего не происходит, как будто он не регистрирует нажатие. только после повторного нажатия я получаю адрес и обновления ярлыков. Я попытался добавить печать и использовать точку останова, чтобы увидеть, регистрируется ли первое касание, и это происходит. Я знаю, что местоположение может занять несколько секунд, чтобы вернуть ответ с адресом, и я ждал, но все равно ничего, только после второго касания, которое оно показывает.

Кажется, как при первом нажатии, Он просто еще не получил адрес. Как я могу "уведомить", когда я получил адрес, и просто попытаться обновить ярлык?

1 Ответ

1 голос
/ 21 июня 2019

Так как didUpdateLocations & reverseGeocodeLocation методы вызываются асинхронно, этот guard может возвращаться с nil address

guard let myResult = self.userAddress else { return }
completion(myResult)

, который не вызовет завершение, необходимое для обновления метки,вместо этого вам нужно

var callBack:((String)->())? 

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
    let userLocation: CLLocation = locations[0] as CLLocation
    geoCoder.reverseGeocodeLocation(userLocation) { (placemarks, err) in
        if let place = placemarks?.last{
           callBack?(place.name!)
        }
    }
}

Затем используйте

location.callBack = { [weak self] str in
   print(str)
   DispatchQueue.main.async { // reverseGeocodeLocation callback is in a background thread 
    // any ui 
   }
}
...