Reputation: 654
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.
Upvotes: 0
Views: 339
Reputation: 1133
In your code, viewDidLoad() function will call the GPSInitialize() function in the CoreLocatinoService class. At this time when it executes the next line of code, 'latitude' value will be nil cause the delegate method of CLLocationManager 'didUpdateLocation' might not get called right away as soon as the startUpdatingLocation() is called.
As a solution of this I would suggest to have another delegate or closure which informs the view controller about the location update and pass the latest location details.
Hope this helps.
Upvotes: 0
Reputation: 10203
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!
Upvotes: 1