在请求用户的iOS位置权限时,我怎么知道是否已经向用户询问了locationManager.requestAlwaysAuthorization()
?
如果用户具有.AuthorizedWhenInUse
状态并且拒绝了始终授权请求,则不会显示下一个请求的always-auth提示,因此我无法获得任何回调此请求启动。
有什么想法吗?
答案 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)
经过反复思考后,我找到了解决方案。
每次应用启动时或在用户查看“设置”应用后进入前台时,检查授权状态。
如果状态为notDetermined
,则请求authorizedWhenInUse
。您不能直接跳到authorizedAlways
。
如果状态为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
}
答案 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)
}
}