fs_tigre
fs_tigre

Reputation: 10738

How to use locationManager() in multiple ViewControllers

I need to get the zipCode and the city in multiple viewControllers.

Here is how I'm currently doing it...

import CoreLocation
let locationManager = CLLocationManager()

class MyViewController: UIViewController, CLLocationManagerDelegate{
    override func viewDidLoad() {
        super.viewDidLoad()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)-> Void in
            if error != nil {
                //AlertView to show the ERROR message
            }

            if placemarks!.count > 0 {
                let placemark = placemarks![0]
                self.locationManager.stopUpdatingLocation()
                let zipCode = placemark.postalCode ?? ""
                let city:String = placemark.locality ?? ""

                // Do something with zipCode
                // Do something with city
            }else{
                print("No placemarks found.")
            }
        })
    }

 func someFunction() {
    locationManager.startUpdatingLocation()
 }

Everything works fine but as you can see doing it this way in multiple viewController leads to a lot of code repetition (of course, I'm not showing the whole code).

What would be the most common way to retrieve the zipCode and city from CLLocationManager() in a more practical way from multiple viewControllers?

What I'm thinking is something like...

 MyLocationManager.zipCode() // returns zipCode as a string 
 MyLocationManager.city() // returns city as a string 

Upvotes: 1

Views: 2183

Answers (2)

matt
matt

Reputation: 535231

The usual thing is to have just one location manager in one persistent place that you can always get to from anywhere, like the app delegate or the root view controller.

Upvotes: 4

emrepun
emrepun

Reputation: 2666

I tried to implement a singleton CLLocationManager class, I think you can modify the following class to implement some additional methods.

import Foundation

class LocationSingleton: NSObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
private var latitude = 0.0
private var longitude = 0.0

static let shared = LocationSingleton()

private override init() {
    super.init()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = kCLLocationAccuracyHundredMeters
    locationManager.requestAlwaysAuthorization() // you might replace this with whenInuse
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let location = locations.last {
        latitude = location.coordinate.latitude
        longitude = location.coordinate.longitude
    }
}

private func getLatitude() -> CLLocationDegrees {
    return latitude
}

private func getLongitude() -> CLLocationDegrees {
    return longitude
}

private func zipCode() {
    // I think you can figure way out to implemet this method
}

private func city() {
    // I think you can figure way out to implemet this method
}
}

Upvotes: 2

Related Questions