Apa yang membuat otorisasi Selalu sementara bersifat sementara?

Aug 16 2020

Menurut Apple, jika Anda meminta aplikasi Lokasi Inti Anda untuk mendapatkan otorisasi Selalu saat otorisasi "tidak ditentukan", pengguna akan melihat dialog untuk otorisasi Saat Dalam Penggunaan tetapi sebenarnya aplikasi Anda mendapatkan otorisasi Selalu - untuk sementara.

Ini berarti bahwa jika Anda tidak benar-benar menggunakan kekuatan Selalu, Anda akan kehilangannya, kembali ke Saat Digunakan.

Oke, tapi kapan pengembalian itu akan terjadi? Sepertinya saya tidak bisa mewujudkannya. Aplikasi saya tetap berada di Selalu otorisasi, meskipun pengguna mengira itu hanya otorisasi Saat Digunakan.

Inilah seluruh kode aplikasi pengujian saya (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())
    }
}

Anda membutuhkan dua tombol dan label. Ketuk tombol pertama untuk meminta Selalu otorisasi ketika Anda tidak memiliki otorisasi untuk memulai ("tidak ditentukan"). Anda melihat dialog When In Use otorization. Berikan otorisasi. Sekarang mainkan dengan aplikasi dan terus menonton tampilan status di label. Anda dapat mengetuk tombol kedua untuk memperbarui status jika diperlukan.

Masalahnya adalah itu tetap di Selalu. Kapan "ketentuan" saya akan berakhir sehingga otorisasi kembali ke When In Use? Bagaimana saya dapat mendorong hal ini terjadi?

Jawaban

5 Rob Aug 16 2020 at 04:12

Dalam What's New in Core Location WWDC 2019 , mereka menguraikan proses dasar di iOS 13.0:

  1. Aplikasi Anda meminta izin "selalu".

  2. Pengguna melihat peringatan izin "saat digunakan", bukan peringatan izin "selalu":

  3. Jika pengguna memberikan "saat digunakan", aplikasi dalam status "selalu sementara".

    Dalam kasus ini, dan agak membingungkan, authorizationStatusakan kembali .authorizedAlwaysketika Anda berada dalam keadaan "selalu sementara" dan aplikasi Pengaturan di ponsel akan menyarankan itu dalam keadaan "saat digunakan". Namun pada kenyataannya, ini dalam keadaan "selalu sementara", tidak sesuai dengan kesimpulan authorizationStatusatau dari apa yang Anda lihat di aplikasi Setelan.

    Tak perlu dikatakan, jika pengguna bahkan tidak mengabulkan "saat digunakan" (misalnya, mereka menolak atau memilih "hanya sekali"), maka jelas Anda tidak akan berada dalam status "selalu sementara".

  4. Ini tetap dalam keadaan sementara sampai, seperti yang dikatakan dalam video, Anda "mulai menggunakan kekuatan 'selalu'". Misalnya, jika Anda memulai layanan perubahan signifikan dan bergerak cukup jauh untuk memicu perubahan signifikan.

    Saat aplikasi "mulai menggunakan kekuatan 'selalu'", OS akan menanyakan pengguna apakah mereka bersedia untuk meningkatkan "saat digunakan" menjadi "selalu". (Ini tidak akan selalu terjadi dengan segera, tetapi akan menunggu hingga pengguna tidak sibuk melakukan hal-hal lain, untuk mengurangi risiko bahwa mereka akan menutup lansiran hanya untuk kembali ke apa yang mereka lakukan.)

Jadi, ini bukan pertanyaan tentang "kembali" ke keadaan lain. Aplikasi akan tetap dalam status "selalu sementara" sampai ada "perjanjian" final (di mana pengguna melihat peringatan kedua dan setuju untuk meningkatkan .authorizedAlwaysatau menolak dan disetel ke .authorizedWhenInUse).


Saya tahu Anda tahu ini, tetapi demi pembaca yang akan datang:

In WWDC 2020 video What's new in location, they describe a change introduced in 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). You just need the appropriate permissions strings.