Search code examples
iosswiftxcodegeolocationcllocationmanager

Where should I instantiate a location manager if my app uses it throughout its various view controllers?


I have an app that uses the user's location throughout its various view conrollers, and I've learned that in order to get that location you need to create a CLLocationManger instance and conform to the CLLocationManagerDelegate protocol.

Is it possible to make one CLLocationManager instance and use it's properties like coordinates in my different view controllers or should I make a CLLocationManager in each view controller class?


Solution

  • A quick and somewhat robust hack could be:

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.startUpdatingLocation()
            return true
         }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            lastLocation = locations.last!
        }
    

    In this same source file, at global scope, add:

    private var lastLocation: CLLocation? {
        didSet { 
            locationCallback?(lastLocation!)
            locationCallback = nil
        }
    }
    
    private var locationCallback: ((CLLocation) -> Void)?
    
    func getLastLocation(callback: (CLLocationManager) -> Void) {
        guard let location = lastLocation else {
            locationCallback = callback
            return
         }
         locationCallback(location)
    }
    

    Finally, elsewhere in your app, you can get your last known location using just:

    getLastLocation { location in
        print(location)
    }