Search code examples
iosswiftcllocationmanager

Using Variable outside locationManager()


I'm trying to clean up my code using MVC Pattern. I have one file "CoreLocationService.swift" where I want to get the location. I want to use the location then in "ViewController.swift" to show it to the user.

CoreLocationService.swift

import Foundation
import CoreLocation

class CoreLocationService: CLLocationManager, CLLocationManagerDelegate {


    let locationManager = CLLocationManager()

    var latitude : Double?


    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let GPS = locations[locations.count - 1] // Get the array of last location

        latitude = GPS.coordinate.latitude


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


    func GPSInitialize() {
        // Start GPS

        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        //locationManager.requestLocation() // One time request
        locationManager.startUpdatingLocation() // Continues location

    }


}

ViewController.swift

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

//    let location = CLLocationManager()

    let locationService = CoreLocationService() // CoreLocationService Class


    override func viewDidLoad() {
        super.viewDidLoad()


        locationService.GPSInitialize() // Start updating Location


        print(locationService.latitude) // Print Latitude

    }

}

i declared latitude as a global variable to access is from ViewController.swift but the variable it empty and prints only "nil".

If I print "Print(latitude)" within locationManager it prints the coordinate.


Solution

  • I think why the latitude is nil when you call print(loccationService.latitude) is that the delegate method

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

    has not updated the latitude yet.

    You could add one callback in CoreLocationService like below,

    // callback to be called after updating location
    var didUpdatedLocation: (() -> ())?
    

    and then call this closure in the delegate method,

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            let GPS = locations[locations.count - 1] // Get the array of last location
    
            latitude = GPS.coordinate.latitude
    
            didUpdatedLocation?()
    }
    

    In your ViewController, print the latitude like this,

    locationService.didUpdatedLocation = {
        print(locationService.latitude) // Print Latitude
    }
    

    Hope this helps!