iOS CLLocationManager in a separate class
As user1071136 said, a singleton location manager is probably what you want. Create a class, a subclass of NSObject, with just one property, a CLLocationManager
.
LocationManagerSingleton.h:
#import <MapKit/MapKit.h>@interface LocationManagerSingleton : NSObject <CLLocationManagerDelegate>@property (nonatomic, strong) CLLocationManager* locationManager;+ (LocationManagerSingleton*)sharedSingleton;@end
LocationManagerSingleton.m:
#import "LocationManagerSingleton.h"@implementation LocationManagerSingleton@synthesize locationManager;- (id)init { self = [super init]; if(self) { self.locationManager = [CLLocationManager new]; [self.locationManager setDelegate:self]; [self.locationManager setDistanceFilter:kCLDistanceFilterNone]; [self.locationManager setHeadingFilter:kCLHeadingFilterNone]; [self.locationManager startUpdatingLocation]; //do any more customization to your location manager } return self;} + (LocationManagerSingleton*)sharedSingleton { static LocationManagerSingleton* sharedSingleton; if(!sharedSingleton) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedSingleton = [LocationManagerSingleton new]; } } return sharedSingleton;}- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { //handle your location updates here}- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { //handle your heading updates here- I would suggest only handling the nth update, because they //come in fast and furious and it takes a lot of processing power to handle all of them}@end
To get the most recently received location, simply use [LocationManagerSingleton sharedSingleton].locationManager.location
. It might take a few seconds to warm up the GPS to get accurate locations.
Create a singleton class which has a latitude
and longitude
properties, startLocating
and endLocating
. In the class, create a CLLocationManager
instance, and set its delegate to be the singleton. In startLocating
and endLocating
, call the appropriate methods of the CLLocationManager
instance. Make the delegate methods update the latitude
and longitude
properties. In other ViewControllers
, read this singleton's latitude
and longitude
properties.
To know when to read those properties from another ViewController
, set an observer on these properties (see the NSKeyValueObserving Protocol Reference
Before doing this, look up the Internets for existing code.
After doing this, upload it to GitHub with a permissive license.
Based on the above answers, here is what I did and you can find the complete example on github https://github.com/irfanlone/CLLocationManager-Singleton-Swift
Just import this file in your project, then you can either choose to implement the LocationUpdateProtocol or listen to notification for location updates
import MapKitprotocol LocationUpdateProtocol { func locationDidUpdateToLocation(location : CLLocation)}/// Notification on update of location. UserInfo contains CLLocation for key "location"let kLocationDidChangeNotification = "LocationDidChangeNotification"class UserLocationManager: NSObject, CLLocationManagerDelegate { static let SharedManager = UserLocationManager() private var locationManager = CLLocationManager() var currentLocation : CLLocation? var delegate : LocationUpdateProtocol! private override init () { super.init() self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.distanceFilter = kCLLocationAccuracyHundredMeters locationManager.requestAlwaysAuthorization() self.locationManager.startUpdatingLocation() } // MARK: - CLLocationManagerDelegate func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) { currentLocation = newLocation let userInfo : NSDictionary = ["location" : currentLocation!] dispatch_async(dispatch_get_main_queue()) { () -> Void in self.delegate.locationDidUpdateToLocation(self.currentLocation!) NSNotificationCenter.defaultCenter().postNotificationName(kLocationDidChangeNotification, object: self, userInfo: userInfo as [NSObject : AnyObject]) } }}
Usage:
class ViewController: UIViewController, LocationUpdateProtocol { var currentLocation : CLLocation! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "locationUpdateNotification:", name: kLocationDidChangeNotification, object: nil) let LocationMgr = UserLocationManager.SharedManager LocationMgr.delegate = self } // MARK: - Notifications func locationUpdateNotification(notification: NSNotification) { let userinfo = notification.userInfo self.currentLocation = userinfo!["location"] as! CLLocation print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } // MARK: - LocationUpdateProtocol func locationDidUpdateToLocation(location: CLLocation) { currentLocation = location print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") }}