如何知道 locationManager.requestAlwaysAuthorization() 是否已经被问到



请求用户的iOS位置权限时,我如何知道是否已向用户请求locationManager.requestAlwaysAuthorization()

如果用户具有.AuthorizedWhenInUse状态并且始终授权的请求被拒绝,则不会显示下一个请求的始终身份验证提示,因此我不会收到此请求启动的任何回调。

有什么想法吗?

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

您可以检查授权状态并比较它是否notDetermined尚未询问,否则 - 是否已询问。

你可以通过使用这样的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

经过大量的头脑风暴,我找到了解决方案。

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

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

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

如您所知,问题是当用户从notDetermined转到notDetermined时,即不会更改其设置。我们需要能够在提示他们之前看到状态。

这实际上很容易,只需将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
}

我面临着同样的问题。这仅对于应用程序更新(在以前版本中未将 authStatus 存储在 UserDefaults 中)不是问题。如果用户决定卸载并重新安装应用程序(删除用户默认值),或者用户手动将状态从"始终"更改为"使用时"(无法知道它已更改为"使用时"或是否一直都是该状态),这也是一个问题。

顺便说一句:用户手动更改授权实际上很常见,因为 iOS 现在每隔一段时间就会发出警报"AppName 一直在后台使用您的位置......你想继续允许这个吗"(或类似的东西不记得了)。我的许多用户在该警报中选择"否",导致"始终"位置访问更改为"使用时",而应用程序没有收到有关该通知的通知。

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

因此,由于缺乏其他选项,我现在正在使用它,老实说,它不是最用户友好的,但它确实有效并且用户友好"足够"(至少对我来说)。

我只是发出一个警报,其中一个按钮指向应用程序的设置页面,用户可以在其中手动更改设置,而不是请求始终授权。如果应用程序之前显示此警报,我确实添加了用户默认存储。如果是这样,我不会再展示它。

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

相关内容

  • 没有找到相关文章

最新更新