Q:

iOS Swift: Request user location

I'm a beginner in iOS Swift and writing iOS Swift code and using UIWebView to load my web page.
And my web page will ask user to enable the user location.
I would like to do the similar behavior in iOS Swift code (popup an dialog and say something like "TestApp would like to access your location. Would you agree?")
I'm running on Simulator and I failed while using CLLocationManager
The following is my Swift code
import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var customWebView: UIWebView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    if let url = NSURL(string: "http://ctrlq.org/maps/where/") {
        let request = NSURLRequest(URL: url)
        customWebView.loadRequest(request)

        let locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()

    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

Anyone knows how to request location?
Thanks in advance.
Eric

A:

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.

A:

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:

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 the NSLocationAlwaysUsageDescription 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 set NSLocationWhenInUseUsageDescription value.)

