O que torna a autorização provisória Sempre provisória?

Aug 16 2020

De acordo com a Apple, se você solicitar que seu aplicativo Core Location obtenha autorização Always quando a autorização "não for determinada", o usuário verá a caixa de diálogo para autorização When In Use, mas, na verdade, seu aplicativo obterá autorização Always - provisoriamente.

Isso significa que, se você não usar seus poderes Sempre, você os perderá, voltando para Quando em uso.

Tá, mas quando vai acontecer essa reversão? Eu não consigo fazer isso acontecer. Meu aplicativo fica apenas na autorização Always, mesmo que o usuário pense que é apenas autorização When In Use.

Aqui está o código completo do meu aplicativo de teste (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())
    }
}

Você precisa de dois botões e um rótulo. Toque no primeiro botão para solicitar autorização Sempre quando você não tiver autorização para começar ("não determinado"). Você vê a caixa de diálogo de autorização When In Use. Conceder autorização. Agora brinque com o aplicativo e continue observando a exibição de status no rótulo. Você pode tocar no segundo botão para atualizar o status, se necessário.

O problema é que fica no Always. Quando minha "provisão" chegará ao fim para que a autorização reverta para When In Use? Como posso encorajar que isso aconteça?

Respostas

5 Rob Aug 16 2020 at 04:12

Em O que há de novo no local principal da WWDC 2019 , eles descrevem o processo básico no iOS 13.0:

  1. Seu aplicativo solicita permissão "sempre".

  2. O usuário vê o alerta de permissão “quando em uso”, não um alerta de permissão “sempre”:

  3. Se o usuário conceder "quando em uso", o aplicativo estará no estado "sempre provisório".

    Nesse caso, e um tanto confuso, o authorizationStatusretornará .authorizedAlwaysquando você estiver nesse estado “sempre provisório” e o aplicativo Configurações no telefone sugerirá que está no estado “quando em uso”. Mas, na realidade, está neste estado “sempre provisório”, não exatamente o que se pode inferir authorizationStatusnem o que você vê no aplicativo Configurações.

    Desnecessário dizer que, se o usuário nem conceder “quando em uso” (por exemplo, ele nega ou escolhe “apenas uma vez”), obviamente você não estará no estado “sempre provisório”.

  4. Ele permanece neste estado provisório até que, como diz o vídeo, você “comece a usar 'sempre' os poderes”. Por exemplo, se você iniciar um serviço de mudança significativa e mover uma distância suficiente para acionar uma mudança significativa.

    Quando o aplicativo “começar a usar poderes 'sempre'”, o sistema operacional perguntará ao usuário se ele deseja atualizar “quando em uso” para “sempre”. (Nem sempre acontecerá imediatamente, mas aguardará até que o usuário não esteja ocupado fazendo outras coisas, para reduzir o risco de que ele ignore o alerta apenas para voltar ao que estava fazendo.)

Então, não se trata de “reverter” para algum outro estado. O aplicativo permanecerá neste estado “sempre provisório” até que haja um “acordo” final (onde o usuário vê o segundo alerta e concorda em atualizar .authorizedAlwaysou nega e é definido como .authorizedWhenInUse).


Eu sei que você sabe disso, mas para o bem dos futuros leitores:

No vídeo WWDC 2020 O que há de novo no local , eles descrevem uma mudança introduzida no iOS 13.4. Em vez do fluxo acima (onde você pede "sempre", o usuário vê as permissões "quando em uso" e não vê o "atualizar para sempre" até que os serviços "sempre" sejam realmente acionados), o iOS 13.4 introduziu um novo fluxo, onde você pode pedir “quando estiver em uso” (em vez de “sempre”) e assumindo que o usuário o concedeu, você pode pedir “sempre” mais tarde, quando apropriado no aplicativo, e o usuário receberá o segundo alerta ( desta vez perguntando se o usuário gostaria de atualizar para “sempre” ou não). Você só precisa das strings de permissões apropriadas.