0

I am trying to get my user's current location using a closure, but it returns a nil value because the locationManager.startUpdatingLocation() sets the value after the closure has returned the (nil) value. I don't know how to wait for the value to get set before I return it using the closure.

This is my location layer:

  class LocationLayer: NSObject {
    static let shared = LocationLayer()
    private let locationManager = CLLocationManager()
    var location: CLLocation?

    override private init() {
        super.init()
        locationManager.delegate = self
    }

    func getCurrentLocation(completion: (CLLocation?) -> ()) {
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        if CLLocationManager.locationServicesEnabled() {
            locationManager.startUpdatingLocation()
        }
        completion(location)
    }
}

    extension LocationLayer: CLLocationManagerDelegate {
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            self.location = locations[0] as CLLocation
            manager.stopUpdatingLocation()
        }
    
        func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
        {
            print("Error \(error)")
        }
    }
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
Maria
  • 31
  • 3

1 Answers1

0

You need

1- Add this to class LocationLayer

var getLoc:(CLLocation-> ())?

2-

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
  self.location = locations[0] as CLLocation
  getLoc?(self.location)
  manager.stopUpdatingLocation()
}

Then inside where you use it do

locationLayerInstance.getLoc = { [weak self] loc in  
   print(loc)
}

3- Finally change

func getCurrentLocation(completion: (CLLocation?) -> ()) {
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    if CLLocationManager.locationServicesEnabled() {
        locationManager.startUpdatingLocation()
    }
    completion(location)
}

To

func startGettingLocation() {
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    if CLLocationManager.locationServicesEnabled() {
        locationManager.startUpdatingLocation()
    } 
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • this would work by calling locationLayerInstance.startGettingLocation() and then locationLayerInstance.getLoc = { [weak self] loc in print(loc) } right? – Maria Mar 29 '22 at 15:28
  • yes , but it's more accurate to reverse them meaning add `locationLayerInstance.getLoc =` then `locationLayerInstance.startGettingLocation() ` that is you set the observer before caller – Shehata Gamal Mar 29 '22 at 15:32