暫定的なAlways認証を暫定的にする理由は何ですか?

Aug 16 2020

Appleによると、認証が「未決定」のときにCore LocationアプリにAlways認証を取得するように要求すると、ユーザーにはWhen In Use認証のダイアログが表示されますが、実際にはアプリはAlways認証を暫定的に取得します。

これは、Alwaysパワーを実際に使用しないと、それらを失い、When InUseに戻ることを意味するはずです。

さて、しかし、その復帰はいつ起こりますか?私はそれを実現できないようです。ユーザーが使用中の承認のみであると考えている場合でも、私のアプリは常に承認のままです。

これが私のテストアプリ(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())
    }
}

2つのボタンと1つのラベルが必要です。最初のボタンをタップして、開始する認証がない場合は常に認証を要求します(「未定」)。「使用中の認証」ダイアログが表示されます。承認を付与します。今度はアプリで遊んで、ラベルのステータス表示を見続けてください。必要に応じて、2番目のボタンをタップしてステータスを更新できます。

問題は、Alwaysにとどまるということです。「プロビジョニング」が終了して、認証が「使用中」に戻るのはいつですか?どうすればこれを奨励できますか?

回答

5 Rob Aug 16 2020 at 04:12

WWDC 2019のコアロケーションの新機能では、iOS13.0の基本的なプロセスの概要を説明しています。

  1. アプリは「常に」許可を要求します。

  2. ユーザーには、「常に」のアクセス許可アラートではなく、「使用中」のアクセス許可アラートが表示されます。

  3. ユーザーが「使用中」を許可した場合、アプリは「暫定常に」状態になります。

    この場合、やや紛らわしいことに、この「暫定常に」状態にauthorizationStatusなるとに戻り.authorizedAlways、電話の設定アプリは「使用中」状態にあることを示唆します。しかし実際には、これはこの「暫定的な常に」の状態でありauthorizationStatus、設定アプリに表示される内容から推測できるものではありません。

    言うまでもなく、ユーザーが「使用中」を許可しない場合(たとえば、「1回だけ」を拒否または選択した場合)、明らかに「常に暫定」状態にはなりません。

  4. ビデオが言うように、あなたが「常に」力を使い始めるまで、それはこの暫定的な状態のままです。たとえば、大幅な変更サービスを開始し、大幅な変更をトリガーするのに十分な距離を移動した場合です。

    アプリが「常に」電源の使用を開始すると、OSは、「使用中」から「常に」にアップグレードするかどうかをユーザーに尋ねます。(常にすぐに発生するわけではありませんが、ユーザーが他のことをするのに忙しくなるまで待機して、ユーザーが行っていたことに戻るためだけにアラートを閉じるリスクを減らします。)

したがって、他の状態に「戻す」ことは問題ではありません。アプリは、最終的な「合意」が得られるまで、この「暫定常に」状態のままになります(ユーザーが2番目のアラートを確認し.authorizedAlways、アップグレードに同意するか拒否して、に設定されます.authorizedWhenInUse)。


私はあなたがこれを知っていることを知っていますが、将来の読者のために:

WWDC 2020ビデオの「ロケーションの新機能」では、iOS13.4で導入された変更について説明しています。上記のフローの代わりに(「常に」を要求すると、ユーザーには「使用中」のアクセス許可が表示され、「常に」サービスが実際にトリガーされるまで「常ににアップグレード」は表示されません)、iOS13.4では新しいフロー。「常に」ではなく「使用中」を要求でき、ユーザーがそれを許可したと仮定すると、アプリで適切な場合は後で「常に」を要求でき、ユーザーは2番目のアラートを受け取ります(今回は、ユーザーが「常に」にアップグレードするかどうかを尋ねます)。適切な権限文字列が必要です。