Reputation: 133
When I run the code, the window pops asking for permission to use location but disappears almost immediately, not giving the user a chance to click "Allow". Is there a way to force this action before proceeding?
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
var map:MKMapView?
var manager:CLLocationManager!
convenience init(frame:CGRect){
self.init(nibName: nil, bundle: nil)
self.view.frame = frame
self.map = MKMapView(frame: frame)
self.map!.delegate = self
self.view.addSubview(self.map!)
}
override func viewDidLoad() {
super.viewDidLoad()
// Core Location
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
}
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus){
print("The authorization status of location services is changed to: ")
switch CLLocationManager.authorizationStatus(){
case .Denied:
println("Denied")
case .NotDetermined:
println("Not determined")
case .Restricted:
println("Restricted")
default:
println("Authorized")
}
}
func displayAlertWithTitle(title: String, message: String){
let controller = UIAlertController(title: title,
message: message,
preferredStyle: .Alert)
controller.addAction(UIAlertAction(title: "OK",
style: .Default,
handler: nil))
presentViewController(controller, animated: true, completion: nil)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if CLLocationManager.locationServicesEnabled(){
switch CLLocationManager.authorizationStatus(){
case .Denied:
displayAlertWithTitle("Not Determined",
message: "Location services are not allowed for this app")
case .NotDetermined:
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
case .Restricted:
displayAlertWithTitle("Restricted",
message: "Location services are not allowed for this app")
default:
println("Default")
}
} else {
println("Location services are not enabled")
}
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
var userLocation:CLLocation = locations[0] as! CLLocation
var latitude:CLLocationDegrees = userLocation.coordinate.latitude
var longitude:CLLocationDegrees = userLocation.coordinate.longitude
var latDelta:CLLocationDegrees = 1.0
var lonDelta:CLLocationDegrees = 1.0
var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
map!.setRegion(region, animated: true)
manager.stopUpdatingLocation()
}
Upvotes: 2
Views: 2435
Reputation: 6544
Please try this:
import UIKit
import GoogleMaps
import CoreLocation
class StartViewController: UIViewController,CLLocationManagerDelegate,GMSMapViewDelegate {
var locationManager: CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
setupLocationManager()
}
func setupLocationManager() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationHandler()
}
func locationHandler() {
if CLLocationManager.locationServicesEnabled() == true {
if (CLLocationManager.authorizationStatus() == .denied) {
// The user denied authorization
} else if (CLLocationManager.authorizationStatus() == .authorizedAlways) {
// The user accepted authorization
} else if (CLLocationManager.authorizationStatus() == .notDetermined){
// The user not determiend authorization
}else if (CLLocationManager.authorizationStatus() == .authorizedWhenInUse){
// In use
}else{ }
}else{
//Access to user location permission denied!
}
}
}//class
Be successful.
Upvotes: 2
Reputation: 3221
It's because you're calling manager.startUpdatingLocation()
before you get the result from the manager.requestWhenInUseAuthorization()
. Even though you call requestWhenInUseAuthorization
, you're updating the user's location before you ever get the result of that method (I had the exact same question as you, actually!)
The answer to that question explains the solution well. Basically, you'll need to implement the locationManager:didChangeAuthorizationStatus
delegate method, which is called any time the authorization status changes based on user input. If the user did authorize tracking, then you can call manager.startUpdatingLocation()
.
Also, for a Swift example of how to implement these methods, take look at this guide.
Upvotes: 1