Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift requestWhenInUseAuthorization not working

I'm writing an app for iOS 9.3 using swift and need a map to show user location. I initialize CLLocationManager and its delegate, I configure info.plist Privacy - Location Usage Description string and invoke requestWhenInUseAuthorization but it does not show any authorization request.

Here is my code:

import UIKit
import MapKit

class DetailController: UIViewController, CLLocationManagerDelegate {

    var locManager: CLLocationManager!

    @IBOutlet var myMap: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        mostraPosizione()
    }

    func mostraPosizione(){
        locManager = CLLocationManager()
        locManager.delegate = self
        locManager.desiredAccuracy = kCLLocationAccuracyBest

        let authorizationStatus = CLLocationManager.authorizationStatus()

        if (authorizationStatus == CLAuthorizationStatus.NotDetermined) {
            locManager.requestWhenInUseAuthorization()
        } else {
            locManager.startUpdatingLocation()
        }


        myMap.showsUserLocation = true
    }

    func locManager(manager: CLLocationManager, 
    didChangeAuthorizationStatus status: CLAuthorizationStatus) {

        if (status == CLAuthorizationStatus.NotDetermined) {
            locManager.requestWhenInUseAuthorization()

        } else {
            locManager.startUpdatingLocation()
        }
    }
}

and a screenshot from my info.plist info.plist

Xcode output:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

I'm testing it on iPhone 5 s (iOS 9.3) simulator.

What's the problem with this stuff? Does anyone have any advice?

like image 277
Andrea Giusti Avatar asked May 01 '16 21:05

Andrea Giusti


1 Answers

Try this on for size:

override func viewDidLoad() {
    super.viewDidLoad()

    //put code here
    locManager = CLLocationManager()
    locManager.delegate = self
    locManager.desiredAccuracy = kCLLocationAccuracyBest
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    //make sure the view is loaded first before adding subviews
    mostraPosizione()
}

func mostraPosizione(){
    let authorizationStatus = CLLocationManager.authorizationStatus()

    if (authorizationStatus == .authorizedWhenInUse) {
        locManager.startUpdatingLocation()
        myMap.showsUserLocation = true
    } else {
        locManager.requestWhenInUseAuthorization()
        mostraPosizione()
    }
}

The reason the request was not showing up was because the view was not completed loaded when the request was called. Using viewDidAppear() fixes that issue.

I made some changes to the code as well, which seems to work great. I only made changes to the code below, other functions remained the same.

I'm writing this code in Swift 3, but the principals are the same.

like image 109
Marlon Mingo Avatar answered Sep 19 '22 12:09

Marlon Mingo