如何知道是否已经询问过locationManager.requestAlwaysAuthorization()

时间:2018-04-12 10:37:04

标签: ios iphone swift ios11

在请求用户的iOS位置权限时,我怎么知道是否已经向用户询问了locationManager.requestAlwaysAuthorization()

如果用户具有.AuthorizedWhenInUse状态并且拒绝了始终授权请求,则不会显示下一个请求的always-auth提示,因此我无法获得任何回调此请求启动。

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

您需要检查CLLocationManager.authorizationStatus(),并且仅在值.notDetermined时请求授权,因为这是实际显示授权提示的唯一情况。

答案 1 :(得分:1)

您可以查看Authorization status并比较是否有notDetermined未询问,否则 - 已被询问。

答案 2 :(得分:1)

你可以这样使用authorizationStatus()来了解。

if CLLocationManager.authorizationStatus() == .notDetermined {
    print("Not Determined")
}
else if CLLocationManager.authorizationStatus() == .restricted {
     print("Restricted")
}
else if CLLocationManager.authorizationStatus() == .denied {
     print("Denied")
}
else if CLLocationManager.authorizationStatus() == .authorizedAlways {
    print("Always Authorized")
}
else if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
    print("Authorized When Require")
}

如果第一次显示对话框,则会返回.notDetermined状态,如果您回复对话框,则会根据您的选择返回状态,如果您允许访问您的位置,则始终返回.authorizedAlways

答案 3 :(得分:1)

经过反复思考后,我找到了解决方案。

  1. 每次应用启动时或在用户查看“设置”应用后进入前台时,检查授权状态。

  2. 如果状态为notDetermined,则请求authorizedWhenInUse。您不能直接跳到authorizedAlways

  3. 如果状态为authorizedWhenInUse,则请求authorizedAlways

众所周知,

捕获是用户从notDeterminednotDetermined的时间,即不更改其设置。我们需要能够在 提示之前查看其状态。

这实际上很容易,只需将CLLocationManager.authorizationStatus()的值保存在名为previousAuthStatus的属性中即可。

private var previousAuthStatus = CLLocationManager.authorizationStatus() 

当应用程序进入前台时,请以先前的状态检查授权状态。

完整代码

不要错过设置previousAuthStatus的最后一位

func checkStatus(_ status: CLAuthorizationStatus) {

    switch status {

    case .notDetermined:

        // request "When in use"
        locationManager.requestWhenInUseAuthorization()

    case .authorizedWhenInUse:

        // already tried requesting "Always"?
        guard previousAuthStatus != .authorizedWhenInUse else {
            <#notify the user...#>
            break
        }

        // otherwise, request "Always"
        locationManager.requestAlwaysAuthorization()

    case .authorizedAlways:

        // start updating location
        <#dismiss any warning you may have displayed#>
        locationManager.startUpdatingLocation()

    case .denied:

        <#notify the user...#>

    case .restricted:

        <#notify the user...#>

    @unknown default:

        break
    }

    // save status for next check
    previousAuthStatus = status
}

答案 4 :(得分:0)

我正面临着同样的问题。这仅对应用程序更新(您未将authStatus存储在先前版本的UserDefaults中)存在问题。如果用户决定卸载并重新安装该应用程序(删除了用户默认设置),或者用户手动将状态从“始终”更改为“使用中”,这也是一个问题(无法得知已将其更改为“何时使用”)处于使用中”或一直处于这种状态)。

顺便说一句:手动更改授权的用户实际上非常普遍,因为iOS现在偶尔会发出一个警报,“ AppName一直在后台使用您的位置...您是否要继续允许这样做”(或类似的东西不记得了)。我的许多用户在该警报中选择“否”,导致“始终”位置访问权限更改为“使用中”,而应用程序未收到有关该通知的通知。

iOS确实会记住之前是否曾经询问过requestAlwaysAccess,无论如何。即使在卸载并重新安装该应用程序之后。

因此,由于没有其他选择,我现在正在使用它,说实话,它不是最用户友好的,但是它确实可以工作并且对用户友好“足够”(至少对我而言)。

我没有提出始终授权的要求,而是只发出了一个警报,其中一个按钮指向应用程序的“设置”页面,然后用户可以在其中手动更改设置。如果应用之前显示了此警报,我确实添加了一个userdefault存储。如果是这样,我将不再显示。

switch CLLocationManager.authorizationStatus() {
    case .restricted, .denied:
        // show an alert with one button opening settings (see below)                   
    case .authorizedAlways:
        // already have always permission, continue with your code
    case .notDetermined:
        // request whenInUse authorisation (you can request always authorisation here too, but iOS won't show 'always' as a choice the first time)
    case .authorizedWhenInUse:
        guard !UserDefaults.showedNoAlwaysAuthorisationAlert else {
            return
        }
        UserDefaults.showedNoAlwaysAuthorisationAlert = true
        // show the alert with "no thanks" and "settings" button
        // button action:
        if 'settingsButtonTapped', let settingsUrl = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(settingsUrl) {
             UIApplication.shared.open(settingsUrl, completionHandler: nil)
        }
}