未调用 requestAlwaysAuthorization 时检测 iOS 14

Detect when requestAlwaysAuthorization not called iOS 14

我正在尝试使用多步骤过程请求用户的位置;但是调用requestAlwaysAuthorization时如果没有执行我想移动显示一个消息

让我通过展示我的流程来更好地解释

这是我目前的流量

  1. 请求While in use
    • 用户选择Allow Once -> 前往2
    • 用户选择Allow While Using App -> 转到2
    • 用户选择Don't Allow -> 显示错误信息
  2. 请求Always permission
    • 用户选择 Keep Only While Using -> 显示错误消息(问题 #1:我无法检测到)
    • 用户选择Change to Always Allow -> 显示成功信息

如果用户从 1 选择 Allow Once 我什至不能调用 requestAlwaysAuthorization 因为调用它不会有任何结果,甚至 Apple 声明

If the user responded to requestWhenInUseAuthorization() with Allow Once, then Core Location ignores further calls to requestAlwaysAuthorization() due to the temporary authorization.

Source

我的目标是,如果用户从 1 中选择 Allow Once,那么应该一起跳过 requestAlwaysAuthorization

如果选择了 1 Allow Wile Using App 并且选择了 requestAlwaysAuthorization Keep Only while using 那么我想知道那个状态。

我知道可以做到,只是不知道怎么做。这是一个可以实现我想要实现的目标的应用程序

从第一张图片开始,用户选择了 Allow While Using App,然后选择了 Keep Only While Using,他们能够检测到它,或者能够检测到对话出现的事实,直到他们没有移动到第三张图片用户回复了。

另一种情况如下:

从用户选择的第一张图片 Allow Once 开始,从第二张图片开始,无论用户选择什么,他们都将转到图片 3,而不显示始终许可(请记住,第二张图片不是真实的许可,它只是用来欺骗用户的按钮);所以他们能够告诉对话没有出现或者用户从上一步中选择了Allow Once(一个或另一个,我不能做任何一个)。

显然我无法将每个组合和 post 记录为 gif,所以如果您想体验应用名称是 Zenly

所以最终目标是能够等待用户响应对话,否则就转到下一个屏幕。

这是我所做的,引用自 apple

Core Location leaves the authorization as When In Use. The delegate doesn’t receive any updates.

我想也许当总是请求时我也应该手动执行委托所以到函数 requestAlwaysLocation() 我添加了行

self.locationManagerDidChangeAuthorization(self.locationManager)

但是,这显然行不通,因为在 Allow While Using App 是从步骤 1 中选择并且 Change to Always Allow 是从步骤 2 中选择的情况下,现在代表将被调用两次...

然后我想如果我可以从步骤 1 检测到配置 When in Use 我也许可以绕过但我不知道该怎么做。

这是LocationManager

的片段
    func requestWhenInUserLocation()  {
        self.locationManager.requestWhenInUseAuthorization()
    }
    
    func requestAlwaysLocation() {
        self.locationManager.requestAlwaysAuthorization()
    }


    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        print("authroizatino changed")
//        let accuracyAuthorization = manager.accuracyAuthorization
        let status = manager.authorizationStatus

        // -change function will just change some internal properties and will post a notification so views that subscribe to it can react accordingly.
        
        switch status {
            case CLAuthorizationStatus.authorizedAlways:
                self.change(permission: .Location, to: .Location(.Always))
                break
            case CLAuthorizationStatus.authorizedWhenInUse:
                self.change(permission: .Location, to: .Location(.WhenInUse))
                break
            case CLAuthorizationStatus.denied:
                self.change(permission: .Location, to: .Denied)
                break
            case CLAuthorizationStatus.notDetermined:
                self.change(permission: .Location, to: .NotDetermined)
                break
            case CLAuthorizationStatus.restricted:
                self.change(permission: .Location, to: .Location(.Restricted))
                break
            @unknown default:
                self.change(permission: .Location, to: .Unknown)
                break
        }
    }


我希望我能够清楚地解释我想要什么

感谢@Paulw11 我能够解决它。其实很简单。

我不能在这里添加任何实现,因为它实际上取决于一个人的用例,而我正在使用 SwiftUI。

所以我所做的是在按下 Request Always 按钮时创建一个 bool 状态并将其设置为 true,我还有一个应用程序活动状态的观察者 这是解决这个问题的关键,我在 bool 状态下也有一个观察员。

如果 bool 状态发生变化而应用程序的活动状态没有发生变化,那么用户选择了 Allow Once;但是,如果状态确实发生了变化,那么我会等待它再次激活。

如果它变为活动状态,我会检查位置权限,如果它仍然是 When in Use 那么用户选择 Keep Only While Using 否则他们选择 Change to Always

所有学分归于 Paulw11

编辑:如果用户从设置更改位置权限,我也有应用程序从后台转到前台的观察器

注意: 如果您使用 Combine 和 SwiftUI,上述算法可以改进很多。我写的大部分都没用,你可以订阅权限和应用的活跃状态。