How can I wait until the LocationService Callback is executed?

242 Views Asked by At

I'm trying to execute a Location Service once. This LocationService is called from another object class, that will add the location info into the parameters. All of this will be one object.

The problem is that when I init the object, everything is populated less the location data, which will be populated a few ms later.

I need to wait until the callback is executed, to successfully generate the full object before using it

So considering that I have the next "LocationService" class

public class LocationService: NSObject, CLLocationManagerDelegate{
    let manager = CLLocationManager()
    var locationCallback: ((CLLocation?) -> Void)!
    var locationServicesEnabled = false
    var didFailWithError: Error?

    public func run(callback: @escaping (CLLocation?) -> Void) {
        locationCallback = callback
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        manager.requestWhenInUseAuthorization()
        locationServicesEnabled = CLLocationManager.locationServicesEnabled()
        if locationServicesEnabled {
            manager.startUpdatingLocation()
        }else {
            locationCallback(nil)
        }
    }

   public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locationCallback(locations.last!)
        manager.stopUpdatingLocation()
    }

    public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        didFailWithError = error
        locationCallback(nil)
        manager.stopUpdatingLocation()
    }

    deinit {
        manager.stopUpdatingLocation()
    }
}

And it is called from the object class like this:

class ObjectX: NSObject{
    //Class variables
    @objc override init() {

    let getLocation = LocationService()
    getLocation.run {
        if let location = $0 {
            //get location parameters
    }}

Finally the ObjectX class is initiated and used from other place

let getLocation = ObjectX()
//After initiate it I use the object for other purposes, but here the object is not complete, the location parameters have not been populated yet

How can I wait in the class that is calling it until the callback is executed? Should I use getLocation.performSelector()? How?

1

There are 1 best solutions below

0
CPI On

Maybe this is not the best way to resolve this but it worked for me.

Basically, instead of creating the ObjectX and setting the in the process, the location service is gonna be called the before, then in the callback, the ObjectX is gonna be initialised, then we can set the location parameters for the ObjectX with the location object the we received in the object.

We remove the location set from the initialiser

class ObjectX: NSObject{
    //Class variables
    @objc override init() {
      //Setting the rest of the parameters that are not location
}}

Then class that was initialising the object, we init and run the LocationService, then in callback we create the ObjectX and we set the location parameters

 let ls = LocationService()
 ls.run { location in
     let objectX = ObjectX()
     objectX.location = location
   //We can use the object here
 }