Swift: CoreLocation 如何知道用户允许什么

Swift: CoreLocation how to know what user allowed

在我的应用程序中,我向用户询问位置权限,并选择始终允许。从 iOS 13 开始,always allow 选项已从弹出窗口中删除。所以我必须创建一个流程并检查 always 选项是否已经启用。

我认为 CLLocationManager.authorizationStatus() return 是用户选择的选项,但不是。

如果我点击 While using the App 选项,它将 return .authorizedAlways,如果我转到应用程序的参数位置,我看到它是 while using the App 选项即已启用。我需要知道 always 选项是否启用

如何操作?

如果您在 iOS 13 上使用 CLLocationManager.requestAlwaysAuthorization() 请求了 "Always" 授权,并且用户在第一个弹出窗口中选择了 "Allow While in Use",那么您的应用会输入所谓的 "Provisional Always Authorization" mode/state。在此期间,您的应用看到的权限和您的用户看到的权限是不同的。位置事件不在后台传递。

Provisional Always 授权在 Apple's WWDC 2019 "What's New in Core Location" 中有详细描述。

快速总结

  1. 您的应用使用 CLLocationManager.requestAlwaysAuthorization()
  2. 请求 "Always" 授权
  3. 向用户显示此弹出窗口:

  1. 用户选择"Allow While in Use"。您应用的 LocationManager 的委托方法 locationManager(_,didChangeAuthorization:) 将使用 .authorizedAlways.
  2. 调用
  3. 用户在 Settings.app 中看到 "While in Use",但您的应用可以使用任何需要 "Always" 权限的方法。

  1. 您的应用使用了需要 "Always" 权限的方法,例如在后台跟踪位置、监控地理围栏事件等。一旦生成这些事件,系统就会保留它们并且不会将它们传递给您应用
  2. 当用户不忙时(在 phone 的主屏幕上停留一段时间),他们会看到另一个弹出窗口,在那里他们可以真正授予 "Always" 授权,从"Provisional Always" 或将应用程序降级为 "While Using" 授权:

  1. 如果用户选择了"Change to Always Allow",只有这样事件才会传送到应用程序。 LocationManager 的委托方法 locationManager(_,didChangeAuthorization:) 将再次使用 .authorizedAlways 调用,或者如果用户选择了 "Keep Only While Using",则将使用 .authorizedWhenInUse 调用。

可能的解决方案

此模式旨在向后兼容使用以前的 iOS SDK 版本编写的应用程序。这些应用程序将看到他们期望看到的内容,他们不会使用 "Provisional Always" 授权接收任何事件。

但这提出了一个挑战,因为没有API来区分真正的"Always"授权和"Provisional Always"。一些可以提供帮助的启发式方法:

  1. 当您第一次在 iOS 13 请求 "Always" 授权并在 return 收到 "Always" 时,这绝对是一个 "Provisional Always" 授权。
  2. 第二个 locationManager(_,didChangeAuthorization:) 调用具有 .authorizedAlways 状态可以表明用户已将应用程序提升到 "Always"。但这是不可靠的,因为这个方法可以在相同的权限状态下被多次调用。例如,每次启动 LocationManager 时。
  3. 当您最终收到您的活动时。例如,在"Provisional Always"授权的时候,后台不会有位置事件,但是如果你开始收到,就代表你真正拥有了"Always"的权限。这就是我想要的。