iOS Swift: Request user location
The correct way to request and update user location(s) is via CLLocationManagerDelegate
.
While your View Controller inherits CLLocationManagerDelegate
, it does not seem to implement the necessary delegate functions. As mentioned by @Rob, you should declare locationManager as a class property, not as a local variable.
This delegate function allows you to implement logic if/when user changes authorization status:
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) { if status == .AuthorizedWhenInUse { // authorized location status when app is in use; update current location locationManager.startUpdatingLocation() // implement additional logic if needed... } // implement logic for other status values if needed...}
This delegate function allows you to implement logic if/when user location has changed:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { if let location = locations.first as? CLLocation { // implement logic upon location change and stop updating location until it is subsequently updated locationManager.stopUpdatingLocation() }}
Furthermore, locationServicesEnabled()
determines whether the user has location services enabled.
You show call do something like this in didFinishLaunchingWithOptions
let status = CLLocationManager.authorizationStatus() if status == .NotDetermined || status == .Denied || status == .AuthorizedWhenInUse { // present an alert indicating location authorization required // and offer to take the user to Settings for the app via // UIApplication -openUrl: and UIApplicationOpenSettingsURLString dispatch_async(dispatch_get_main_queue(), { let alert = UIAlertController(title: "Error!", message: "GPS access is restricted. In order to use tracking, please enable GPS in the Settigs app under Privacy, Location Services.", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Go to Settings now", style: UIAlertActionStyle.Default, handler: { (alert: UIAlertAction!) in print("") UIApplication.sharedApplication().openURL(NSURL(string:UIApplicationOpenSettingsURLString)!) })) // self.presentViewController(alert, animated: true, completion: nil) self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil) }) locationManager.requestAlwaysAuthorization() locationManager.requestWhenInUseAuthorization() }
A couple of thoughts:
You've defined your
CLLocationManager
as a local variable, which will get released when it falls out of scope.Make this a property of your class.
If you really need
requestAlwaysAuthorization
, don't forget to set theNSLocationAlwaysUsageDescription
in the plist as outlined in the documentation.(And if you don't need always authorization, but are ok with "in use" authorization, call
requestWhenInUseAuthorization
and setNSLocationWhenInUseUsageDescription
value.)