2

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()

}
Pablo Picasso
  • 133
  • 2
  • 12
  • possible duplicate of [Xcode warning when using MapKit and CoreLocation](http://stackoverflow.com/questions/30495288/xcode-warning-when-using-mapkit-and-corelocation) – JAL Jun 09 '15 at 16:27
  • I tried doing exactly that and updated my question to include what I implemented but now it does't even prompt the user to enable location services. – Pablo Picasso Jun 09 '15 at 16:43

2 Answers2

2

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.

reza_khalafi
  • 6,230
  • 7
  • 56
  • 82
1

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.

Community
  • 1
  • 1
narner
  • 2,908
  • 3
  • 26
  • 63
  • I tried doing exactly that and updated my question to include what I implemented but now it does't even prompt the user to enable location services. – Pablo Picasso Jun 09 '15 at 16:43
  • @PabloPicasso, did you add the `NSLocationUsageDescription` string in your `Info.plist` file? (See "Knowing When to Start Location Services": https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html) – narner Jun 09 '15 at 17:12
  • I didn't. I want location services to be enabled, every time the app is launched. – Pablo Picasso Jun 09 '15 at 17:18
  • @PabloPicasso The problem is, upon the first launch of an app by a user, location services shouldn't be enabled until it's given permission. That's besides the point though---what that string does is provide the user with a description of why you want to get their location. – narner Jun 09 '15 at 17:23
  • I have NSLocationWhenInUseUsageDescription added to the p.list . before when I didn't include switch CLLocationManager.authorizationStatus(), it prompted the user to allow location services, but now it doesn't do it at all – Pablo Picasso Jun 09 '15 at 17:27