4

I am using iOS SDK 8.1 trying to call requestWhenInUseAuthorization() method to prompt user to grant access to my app. I imported CoreLocation.framework, and added NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription keys into info.plist. When I ran the app, it never prompted me for location access. Below is my code, what have I missed?

import UIKit
import CoreLocation
import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        var manager = CLLocationManager()
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest

        let authorizationStatus = CLLocationManager.authorizationStatus()
        switch authorizationStatus {
        case .Authorized:
            println("authorized")
        case .AuthorizedWhenInUse:
            println("authorized when in use")
        case .Denied:
            println("denied")
        case .NotDetermined:
            println("not determined")
        case .Restricted:
            println("restricted")
        }

        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()

    }

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
        let location = locations[0] as CLLocation
        println("Latitude: \(location.coordinate.latitude). Longitude: \(location.coordinate.longitude).")
    }

    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .Authorized:
            println("authorized")
        case .AuthorizedWhenInUse:
            println("authorized when in use")
        case .Denied:
            println("denied")
        case .NotDetermined:
            println("not determined")
        case .Restricted:
            println("restricted")
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

The console only showed "not determined" once and nothing else. So I went to iPhone Simulator => Settings => Privacy => Location => My App. It showed me 3 options: "Never", "While Using the App", "Always". But nothing was selected.

toadead
  • 1,038
  • 16
  • 29

3 Answers3

21

Problem solved. My manager was declared as local var inside viewDidLoad() method, but it should've been a class level property.

After I moved manager declaration out of viewDidLoad(), my app worked.

Not sure how exactly manager.requestWhenInUseAuthorization() work behind the scene and why exactly manager defined within viewDidLoad() not work. Hope someone who knows this detail enlighten me.

Nagendra Rao
  • 7,016
  • 5
  • 54
  • 92
toadead
  • 1,038
  • 16
  • 29
  • 1
    If the manager is defined as a local variable in viewDidLoad(), it will be released from memory at the end of the method. Thus, the calls to requestWhenInUseAuthorization() and startUpdatingLocation() would work, but once the manager is released, it would stop updating the location and would never call the delegate. – Eneko Alonso May 07 '15 at 19:19
  • FINALLY I find the solution! Normally when I use location services I have a singleton that handles everything, but in trying to rapid prototype some location services stuff I hadn't gotten so far as to implement the singleton method, and thus as you said the object didn't stick around... – Mike Jun 08 '15 at 00:34
1

Setting these properties in the viewWillAppear instead of the viewDidLoad fixed it for me, thanks!

override func viewWillAppear(animated: Bool) {

    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
  }
rcmadruga
  • 817
  • 12
  • 18
7RedBits.com
  • 454
  • 6
  • 6
0

I also faced the same problem. I have added two keys together in info.plist.

enter image description here

NSLocationWhenInUseUsageDescription key is supported in iOS 8.0 and later. If your Info.plist file includes both this key and the NSLocationUsageDescription key, the system uses this key and ignores the NSLocationUsageDescription key.

Rearranged the code:

let locationManager: CLLocationManager = CLLocationManager()
  let authorizationStatus = CLLocationManager.authorizationStatus()

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager.delegate = self
    if(authorizationStatus == .Denied)
    {
      print("DENIED")
      locationManager.requestWhenInUseAuthorization()
    }

  }
override func viewWillAppear(animated: Bool) {

    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
  }

Clean the project and run again.

Alvin George
  • 14,148
  • 92
  • 64