¿Qué hace provisional la autorización Siempre provisional?

Aug 16 2020

Según Apple, si solicita que su aplicación Core Location obtenga la autorización Siempre cuando la autorización "no está determinada", el usuario ve el cuadro de diálogo para la autorización Cuando está en uso, pero de hecho su aplicación obtiene la autorización Siempre, provisionalmente.

Se supone que esto significa que si no usa sus poderes Siempre, los perderá y volverá a Cuando esté en uso.

Está bien, pero ¿cuándo ocurrirá esa reversión? Parece que no puedo hacer que suceda. Mi aplicación solo permanece en la autorización Siempre, aunque el usuario cree que solo tiene autorización Cuando está en uso.

Aquí está el código completo de mi aplicación de prueba (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())
    }
}

Necesitas dos botones y una etiqueta. Toque el primer botón para solicitar la autorización Siempre cuando no tenga autorización para comenzar ("no determinado"). Verá el cuadro de diálogo de autorización When In Use. Otorgar autorización. Ahora juegue con la aplicación y siga observando la pantalla de estado en la etiqueta. Puede tocar el segundo botón para actualizar el estado si es necesario.

El problema es que se queda en Siempre. ¿Cuándo terminará mi "provisión" para que la autorización vuelva a When In Use? ¿Cómo puedo alentar a que esto suceda?

Respuestas

5 Rob Aug 16 2020 at 04:12

En What's New in Core Location de WWDC 2019 , describen el proceso básico en iOS 13.0:

  1. Su aplicación solicita permiso "siempre".

  2. El usuario ve una alerta de permisos "cuando está en uso", no una alerta de permisos "siempre":

  3. Si el usuario otorga "cuando está en uso", la aplicación está en estado "siempre provisional".

    En este caso, y de manera un tanto confusa, authorizationStatusvolverá .authorizedAlwayscuando se encuentre en este estado "siempre provisional" y la aplicación Configuración del teléfono sugerirá que está en estado "cuando esté en uso". Pero en realidad, está en este estado "siempre provisional", no exactamente de lo que uno podría inferir authorizationStatusni de lo que ve en la aplicación Configuración.

    No hace falta decir que si el usuario ni siquiera otorga "cuando está en uso" (por ejemplo, niega o elige "solo una vez"), entonces obviamente no estará en el estado "siempre provisional".

  4. Permanece en este estado provisional hasta que, como dice el vídeo, "empiezas a usar los poderes de 'siempre'". Por ejemplo, si inicia un servicio de cambio significativo y se mueve una distancia suficiente para desencadenar un cambio significativo.

    Cuando la aplicación "comience a usar los poderes 'siempre'", el sistema operativo le preguntará al usuario si está dispuesto a actualizar "cuando esté en uso" a "siempre". (No siempre sucederá de inmediato, sino que esperará hasta que el usuario no esté ocupado haciendo otras cosas, para reducir el riesgo de que descarte la alerta solo para volver a lo que estaba haciendo).

Entonces, no se trata de “revertir” a algún otro estado. La aplicación permanecerá en este estado "siempre provisional" hasta que haya un "acuerdo" final (donde el usuario ve la segunda alerta y acepta actualizar .authorizedAlwayso rechaza y se establece en .authorizedWhenInUse).


Sé que lo sabes, pero por el bien de los futuros lectores:

En el video WWDC 2020 What's new in location , describen un cambio introducido en iOS 13.4. En lugar del flujo anterior (donde solicita "siempre", el usuario ve los permisos "cuando está en uso" y no ve la "actualización a siempre" hasta que los servicios "siempre" se activen), iOS 13.4 introdujo un nuevo flujo, donde puede solicitar "cuando esté en uso" (en lugar de "siempre") y, suponiendo que el usuario lo autorice, puede solicitar "siempre" más adelante, cuando corresponda en la aplicación, y el usuario recibe la segunda alerta ( esta vez preguntando si al usuario le gustaría actualizar a "siempre" o no). Solo necesita las cadenas de permisos adecuadas.