Swift requestWhenInUseAuthorization 不起作用

Posted

技术标签:

【中文标题】Swift requestWhenInUseAuthorization 不起作用【英文标题】:Swift requestWhenInUseAuthorization not working 【发布时间】:2016-08-26 14:38:32 【问题描述】:

我正在使用 swift 为 ios 9.3 编写一个应用程序,需要一张地图来显示用户位置。 我初始化 CLLocationManager 及其委托,我配置 info.plist Privacy - Location Usage Description 字符串并调用 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 的屏幕截图

Xcode 输出:

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

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

这东西有什么问题? 有人有什么建议吗?

【问题讨论】:

我认为您在使用 plist 中的描述键时缺少位置 【参考方案1】:

我觉得是因为

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)

【讨论】:

authorizationStatus == nil 不能作为解决方案,因为“'CLAuthorizationStatus' 类型的值永远不能为零,不允许比较” 很高兴可以通过直接进入我们应用程序的设置来设置授权! UIApplicationOpenSettingsURLString 现在是UIApplication.openSettingsURLString【参考方案2】:

试穿一下尺寸:

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 中编写此代码,但原理相同。

【讨论】:

在 mostraPosizione() 中调用 mostraPosizione() 会创建一个无限循环,直到用户不与视图交互。这是不好的。一段时间后它崩溃了 正确的答案是Chajmz的答案,在最后一部分:如果用户拒绝授权,弹出窗口将不再显示。 在我的例子中,requestWhenInUseAuthorization 呈现了一个被立即关闭的模式。即使您及时单击“接受”,它也不会调用 didChangeAuthorization 委托方法。通过将 CLLocationManager 初始化调用与 viewDidLoad 和 viewDidAppear 中的方法调用分开,我终于看到了预期的行为【参考方案3】:

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

【讨论】:

我不知道为什么-我删除了以前的密钥并将其更改为新密钥,瞧,它有效! :-)【参考方案4】:

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

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

但这还不够。 elight 的评论(19 年 1 月 25 日)关于将 CLLocationManager 的调用从请求中分离出来也是必需的。我必须声明一个属性,在 viewDidLoad() 中对其进行初始化,然后稍后调用 requestWhenInUseAuthorization()。

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

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

【讨论】:

以上是关于Swift requestWhenInUseAuthorization 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Swift入门系列--Swift官方文档(2.2)--中文翻译--About Swift 关于Swift

swift 示例BS swift.swift

swift swift_bug.swift

ios 整理(一)swift和oc的区别

swift swift_extension5.swift

swift swift_optional4.swift