是什么使临时的“始终授权”成为临时的?

问题描述

根据苹果公司的说法,如果您要求“核心位置”应用在“未确定”授权时获得“始终”授权,则用户会看到“使用中”授权对话框,但实际上您的应用已获得“始终”授权-暂时。 / p>

这应该意味着,如果您实际上没有使用您的“始终”电源,您将失去它们,恢复为“使用时”。

好的,但是什么时候会恢复原状?我似乎无法实现。即使 user 认为它只是“使用中”授权,我的应用仍处于“始终”授权状态。

这是我的测试应用(iOS 14)的全部代码

class ViewController: UIViewController,CLLocationManagerDelegate {
    @IBOutlet weak var label: UILabel!
    
    let locman = CLLocationManager()
    override func viewDidLoad() {
        super.viewDidLoad()
        locman.delegate = self
    }

    @IBAction func doAskForAlways(_ sender: Any) {
        self.checkForLocationAccess(always:true)
    }
    
    func checkForLocationAccess(always:Bool = false,andThen f: (()->())? = nil) {
        let status = self.locman.authorizationStatus()
        switch status {
        case .authorizedWhenInUse:
            if always { // try to step up
                self.locman.requestAlwaysAuthorization()
            } else {
                f?()
            }
        case .authorizedAlways:
            f?()
        case .notDetermined:
            if always {
                self.locman.requestAlwaysAuthorization()
            } else {
                self.locman.requestWhenInUseAuthorization()
            }
        case .restricted:
            break
        case .denied:
            break
        default: fatalError()
        }
    }
    
    fileprivate func updateStatus(_ status: CLAuthorizationStatus) {
        self.label.text = {
            switch status {
            case .authorizedAlways: return "Always"
            case .authorizedWhenInUse: return "When In Use"
            default: return ""
            }
        }()
    }
    
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        let status = manager.authorizationStatus()
        print("authorization is",status.rawValue)
        updateStatus(status)
    }
    
    @IBAction func doStatus(_ sender: Any) {
        self.updateStatus(self.locman.authorizationStatus())
    }
}

您需要两个按钮和一个标签。当您无权以(“不确定”)开头时,请点击第一个按钮以询问“始终授权”。您会看到“使用中授权”对话框。授予授权。现在使用该应用程序,并继续观察标签中的状态显示。如果需要,您可以点击第二个按钮以更新状态。

问题在于它始终处于“始终”状态。我的“设置”何时结束,以便授权恢复为“使用中”?我如何鼓励这种情况发生?

解决方法

在WWDC 2019的What's New in Core Location中,他们概述了iOS 13.0的基本过程:

  1. 您的应用请求“始终”许可。

  2. 用户看到“使用中”权限警报,而不是“始终”权限警报:

    enter image description here

  3. 如果用户授予“使用时”,则该应用程序将处于“始终设置为临时”状态。

    在这种情况下,并且有些令人困惑,当您处于“总是临时”状态时,authorizationStatus将返回.authorizedAlways,并且手机上的“设置”应用会建议其处于“正在使用中”状态州。但实际上,它处于这种“始终为临时”状态,不完全是根据authorizationStatus或您在“设置”应用中看到的内容得出的结论。

    不用说,如果用户甚至不授予“使用时”(例如,他们拒绝或选择“仅一次”),那么显然您将不会处于“总是临时”状态。

  4. 它会一直保持这种临时状态,直到视频所述,您“开始使用'always'的电源”。例如,如果您启动重大更改服务并移动足以触发重大更改的距离。

    当应用确实“开始使用“总是”使用电源”时,操作系统将询问用户是否愿意将“使用中”升级为“始终”。 (它不会总是立即发生,而是会一直等到用户不忙于做其他事情时,以减少他们为了恢复到正在做的事情而放弃警报的风险。)

    enter image description here

因此,这不是“恢复”到其他状态的问题。在最终达成“协议”之前,该应用将一直保持“临时保留”状态(用户看到第二条警报,并同意升级到.authorizedAlways或拒绝并设置为.authorizedWhenInUse


我知道您知道这一点,但是为了将来的读者:

在WWDC 2020视频What's new in location中,他们描述了iOS 13.4中引入的更改。 iOS 13.4引入了一种替代方法,而不是上面的流程(您要求“始终”,用户会看到“使用时”权限,并且在实际触发“始终”服务之前他们不会看到“升级到始终”)。新流程,您可以在其中询问“何时使用”(而不是“始终”),并假设用户已授予它,则可以稍后在应用程序中的适当位置询问“始终”,然后用户会收到第二次警报(这次询问用户是否要升级到“始终”)。您只需要适当的权限字符串即可。