简体   繁体   English

是什么让临时性 Always 授权是临时性的?

[英]What makes provisional Always authorization provisional?

According to Apple, if you ask for your Core Location app to get Always authorization when the authorization is "not determined", the user sees the dialog for When In Use authorization but in fact your app gets Always authorization — provisionally.根据 Apple 的说法,如果您在“未确定”授权时要求您的 Core Location 应用程序获得 Always 授权,用户会看到“使用时”授权的对话框,但实际上您的应用程序会临时获得 Always 授权。

This is supposed to mean that if you don't actually use your Always powers, you will lose them, reverting to When In Use.这应该意味着如果你没有真正使用你的 Always 能力,你将失去它们,恢复到使用时。

Okay, but when will that reversion happen?好的,但是什么时候会发生这种逆转? I can't seem to make it happen.我似乎无法实现它。 My app just stays at Always authorization, even though the user thinks it is only When In Use authorization.我的应用程序只是保持始终授权,即使用户认为它只是在使用时授权。

Here's the entire code of my test app (iOS 14):这是我的测试应用程序(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())
    }
}

You need two buttons and a label.您需要两个按钮和一个 label。 Tap the first button to ask for Always authorization when you have no authorization to start with ("not determined").当您无权开始时(“未确定”),点击第一个按钮以请求始终授权。 You see the When In Use authorization dialog.您会看到“使用时授权”对话框。 Grant authorization.授予授权。 Now play with the app and keep watching the status display in the label.现在玩应用程序并继续观察 label 中的状态显示。 You can tap the second button to update the status if needed.如果需要,您可以点击第二个按钮来更新状态。

The problem is that it stays at Always.问题是它始终保持不变。 When will my "provision" come to an end so that the authorization reverts to When In Use?我的“规定”何时结束,以便授权恢复为“使用时”? How can I encourage this to happen?我怎样才能鼓励这种情况发生?

In WWDC 2019's What's New in Core Location , they outline the basic process in iOS 13.0:在 WWDC 2019 的核心位置新增功能中,他们概述了 iOS 13.0 中的基本流程:

  1. Your app requests “always” permission.您的应用请求“始终”权限。

  2. The user sees “when in use” permissions alert, not an “always” permission alert:用户会看到“使用时”权限警报,而不是“始终”权限警报:

    在此处输入图像描述

  3. If the user grants “when in use” the app is in “provisional always” state.如果用户授予“使用时”,则应用程序处于“始终临时”state。

    In this case, and somewhat confusingly, the authorizationStatus will return .authorizedAlways when you are in this “provisional always” state and the Settings app on the phone will suggest it's in “when in use” state.在这种情况下,有点令人困惑的是,当您处于此“临时始终”state 时, authorizationStatus将返回.authorizedAlways ,并且手机上的“设置”应用程序将提示它处于“使用时”state 中。 But in reality, it's in this “provisional always” state, not quite what one might infer from authorizationStatus nor from what you see in the Settings app.但实际上,它存在于这个“临时性的”state 中,这与从authorizationStatus或您在“设置”应用程序中看到的推断不同。

    Needless to say, if the user doesn't even grant “when in use” (eg they deny or chose “only once”), then obviously you won't be in “provisional always” state.不用说,如果用户甚至没有授予“使用时”(例如,他们拒绝或选择“仅一次”),那么显然您不会处于“临时始终”state 中。

  4. It remains in this provisional state until, as the video says, you “start using 'always' powers”.它保留在这个临时的 state 中,直到如视频所述,您“开始使用‘始终’的权力”。 For example, if you start significant change service and move a distance sufficient to trigger a significant change.例如,如果您启动重大变更服务并移动足以触发重大变更的距离。

    When the app does “start using 'always' powers”, the OS will ask the user if they are is willing to upgrade “when in use” to “always”.当应用程序确实“开始使用 'always' 权限”时,操作系统会询问用户是否愿意将“when in use”升级为“always”。 (It won't always happen immediately, but will wait until the user is not busy doing other things, to reduce the risk that they'll dismiss the alert just to get back to what they were doing.) (它不会总是立即发生,但会等到用户不忙于做其他事情,以减少他们为了回到他们正在做的事情而解除警报的风险。)

    在此处输入图像描述

So, it's not a question of “reverting” to some other state.因此,这不是“恢复”到其他一些 state 的问题。 The app will remain in this “provisional always” state until there is final “agreement” (where the user sees the second alert and either agrees to upgrade to .authorizedAlways or denies and it is set to .authorizedWhenInUse ).该应用程序将保留在此“临时始终” state 中,直到最终“同意”(用户看到第二个警报并同意升级到.authorizedAlways或拒绝并设置为.authorizedWhenInUse )。


I know you know this, but for the sake of future readers:我知道你知道这一点,但为了未来的读者:

In WWDC 2020 video What's new in location , they describe a change introduced in iOS 13.4.在 WWDC 2020 视频What's new in location 中,他们描述了 iOS 13.4 中引入的更改。 Instead of the flow above (where you ask for “always”, the user sees “when in use” permissions, and they don't see the “upgrade to always” until “always” services are actually triggered), iOS 13.4 introduced a new flow, where you can ask for “when in use” (rather than “always”) and assuming the user granted it, you can ask for “always” later, where appropriate in the app, and the user get the second alert (this time asking if the user would like to upgrade to “always” or not). iOS 13.4 不是上面的流程(您要求“始终”,用户看到“使用时”权限,并且在实际触发“始终”服务之前他们看不到“升级到始终”),iOS 13.4 引入了新流程,您可以在其中询问“使用时”(而不是“始终”)并假设用户授予它,您可以稍后在应用程序中的适当位置询问“始终”,并且用户会收到第二个警报(这次询问用户是否愿意升级到“始终”)。 You just need the appropriate permissions strings.您只需要适当的权限字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM