Swift requestWhenInUseAuthorization无法正常工作

时间:2016-05-01 21:24:34

标签: swift location cllocationmanager

我正在使用swift为iOS 9.3编写应用,需要一张地图来显示用户位置。 我初始化 CLLocationManager 及其委托,我配置info.plist 隐私 - 位置使用说明字符串并调用 requestWhenInUseAuthorization 但它未显示任何授权请求。

这是我的代码:

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

和我的info.plist截图 info.plist

Xcode输出:

  

尝试在不提示位置授权的情况下启动MapKit位置更新。   必须调用 - [CLLocationManager requestWhenInUseAuthorization]   或者 - [CLLocationManager requestAlwaysAuthorization]首先。

我正在iPhone 5(iOS 9.3)模拟器上测试它。

这个东西有什么问题? 有没有人有任何建议?

4 个答案:

答案 0 :(得分:7)

我认为是因为

let authorizationStatus = CLLocationManager.authorizationStatus()

nil,因此您的requestWhenInUseAuthorization()永远不会被调用。

  let authorizationStatus = CLLocationManager.authorizationStatus()

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

应该有效。

修改

如果用户拒绝请求,您还应该处理此案例

if (authorizationStatus == CLAuthorizationStatus.Denied ) {
  // Display a message, do what you want 
}

实际上,一旦用户拒绝了授权,您就无法再次显示弹出窗口,用户必须进入应用设置并自行设置使用其位置的授权。但是,您现在可以直接从应用程序链接到设置,因此对用户来说更容易。

// Open the settings of your app
if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
    UIApplication.sharedApplication().openURL(url)
}

答案 1 :(得分:3)

尝试使用此尺寸:

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

请求未显示的原因是因为在调用请求时未加载视图。使用viewDidAppear()修复了该问题。

我也对代码做了一些更改,这看起来效果很好。我只对下面的代码进行了更改,其他功能保持不变。

我在Swift 3中编写这段代码,但是这些代码是相同的。

答案 2 :(得分:2)

将NSLocationWhenInUseUsageDescription键添加到info.plist是解决方案。

答案 3 :(得分:1)

我的目标是 iOS 14。我只做使用时

我必须拥有所有三个字符串:

enter image description here

但这还不够。 elight 的评论(19 年 1 月 25 日)关于将 CLLocationManager 的调用与请求分开的评论也被证明是必需的。我必须声明一个属性,在 viewDidLoad() 中初始化它,然后稍后调用 requestWhenInUseAuthorization()。

最后,在测试时,删除应用程序还不够。我在另一个 SO 答案上看到了一条评论,其中该开发人员在删除他们的应用程序后必须打开“设置”应用程序以再次测试。事实证明,这对我来说也是必需的。

说真的,我不会拉你的腿。