如何return函数中CLLocationManager didUpdateLocations的值?

How to return the value of CLLocationManager didUpdateLocations in function?

我遇到的问题是,当我在其他 类 中调用 getCityName() 函数时,它 return 为零,因为 didUpdateLocations 需要更多时间 运行,如何解决这个问题异步问题?以及如何return函数中CLLocationManager didUpdateLocations的值?

import Foundation
import CoreLocation

class userCurrentLocation: NSObject, CLLocationManagerDelegate {

    var locationManager:CLLocationManager!
    var cityName:String!

     init(cityName:String) {
        super.init()
        setUp()
    }

    func getCityName() -> String?{
        return cityName
    }

    func setUp() {
        if (CLLocationManager.locationServicesEnabled())
        {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.requestWhenInUseAuthorization()
            locationManager.startUpdatingLocation()
        }
    }

     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locations.last!.geocode { placemark, error in
            if let error = error as? CLError {
                print("CLError:", error)
                return
            } else if let placemark = placemark?.first {
                    self.cityName = placemark.locality ?? ""
                    manager.stopUpdatingLocation()
            }
        }
    }

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

extension CLLocation {
    func geocode(completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)  {
        CLGeocoder().reverseGeocodeLocation(self, completionHandler: completion)
    }
}
class userCurrentLocation: NSObject, CLLocationManagerDelegate {

    var locationManager:CLLocationManager!
    var cityName:String!


    //1. Add a closure callback
    var didGetCity: ((String) -> Void)?


    //2. Send City Name when received
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locations.last!.geocode { placemark, error in
            if let error = error as? CLError {
                print("CLError:", error)
                return
            } else if let placemark = placemark?.first {
                    self.cityName = placemark.locality ?? ""

                    // Check for null 
                    // Send city name in the completion block
                    if (self.didGetCity != nil){
                    self.didGetCity?(self.cityName)
                    }
                    manager.stopUpdatingLocation()
            }
        }
    }


    //3. Add code to your class where you need the city Name

    var City : String?


    let locationManager = userCurrentLocation (cityName: "")
        locationManager.didGetCity = {
            [weak self] city in
            self!.City = city
        }

您可以使用 Delegate 告诉 main class 一切就绪并使用该值

import Foundation
import CoreLocation


protocol userCurrentLocationDelegate: class {
  func userCurrentLocationDidGetLocation(_ userLocation: userCurrentLocation)
}

class userCurrentLocation: NSObject, CLLocationManagerDelegate {

    var locationManager:CLLocationManager!
    var cityName:String!
    weak var delegate: userCurrentLocationDelegate?

 init(cityName:String) {
    super.init()
    setUp()
}

func getCityName() -> String?{
    return cityName
}

func setUp() {
    if (CLLocationManager.locationServicesEnabled())
    {
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
}

 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    locations.last!.geocode { placemark, error in
        if let error = error as? CLError {
            print("CLError:", error)
            return
        } else if let placemark = placemark?.first {
                self.cityName = placemark.locality ?? ""
                manager.stopUpdatingLocation()
                delegate?.userCurrentLocationDidGetLocation(self)
        }
    }
}

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

}

extension CLLocation {
    func geocode(completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)  {
        CLGeocoder().reverseGeocodeLocation(self, completionHandler: completion)
    }
}

并且在 Main class 中调用这个回调使用委托来开始调用城市名称