Qu'est-ce qui rend provisoire l'autorisation Toujours provisoire ?
Selon Apple, si vous demandez à votre application Core Location d'obtenir toujours l'autorisation lorsque l'autorisation n'est « pas déterminée », l'utilisateur voit la boîte de dialogue de l'autorisation When In Use, mais en fait, votre application obtient toujours l'autorisation — provisoirement.
Cela est censé signifier que si vous n'utilisez pas réellement vos pouvoirs Always, vous les perdrez et reviendrez à When In Use.
D'accord, mais quand cette inversion se produira-t-elle ? Je n'arrive pas à y arriver. Mon application reste simplement sur l'autorisation Always, même si l' utilisateur pense qu'il s'agit uniquement de l'autorisation When In Use.
Voici le code complet de mon application de test (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())
}
}
Vous avez besoin de deux boutons et d'une étiquette. Appuyez sur le premier bouton pour demander l'autorisation Toujours lorsque vous n'avez aucune autorisation pour commencer ("non déterminé"). La boîte de dialogue d'autorisation En cas d'utilisation s'affiche. Accorder l'autorisation. Jouez maintenant avec l'application et continuez à regarder l'affichage de l'état dans l'étiquette. Vous pouvez appuyer sur le deuxième bouton pour mettre à jour le statut si nécessaire.
Le problème est qu'il reste à Always. Quand ma "mise à disposition" prendra-t-elle fin pour que l'autorisation revienne à When In Use ? Comment puis-je encourager cela?
Réponses
Dans What's New in Core Location de WWDC 2019 , ils décrivent le processus de base dans iOS 13.0 :
Votre application demande l'autorisation "toujours".
L'utilisateur voit une alerte d'autorisation "en cours d'utilisation", et non une alerte d'autorisation "toujours" :
Si l'utilisateur accorde "lors de l'utilisation", l'application est dans l'état "toujours provisoire".
Dans ce cas, et quelque peu déroutant, le
authorizationStatus
reviendra.authorizedAlways
lorsque vous serez dans cet état "provisoire toujours" et l'application Paramètres sur le téléphone suggérera qu'il est dans l'état "lors de l'utilisation". Mais en réalité, c'est dans cet état "toujours provisoire", pas tout à fait ce que l'on pourrait déduireauthorizationStatus
ni de ce que vous voyez dans l'application Paramètres.Inutile de dire que si l'utilisateur n'accorde même pas "lors de l'utilisation" (par exemple, il refuse ou choisit "une seule fois"), alors vous ne serez évidemment pas dans l'état "provisoire toujours".
Il reste dans cet état provisoire jusqu'à ce que, comme le dit la vidéo, vous "commenciez à utiliser 'toujours' les pouvoirs". Par exemple, si vous démarrez un service de changement significatif et que vous vous déplacez sur une distance suffisante pour déclencher un changement significatif.
Lorsque l'application "commence à utiliser les pouvoirs 'toujours'", le système d'exploitation demande à l'utilisateur s'il souhaite mettre à niveau "lorsqu'il est utilisé" vers "toujours". (Cela ne se produira pas toujours immédiatement, mais attendra que l'utilisateur ne soit pas occupé à faire autre chose, pour réduire le risque qu'il ignore l'alerte juste pour revenir à ce qu'il était en train de faire.)
Il ne s'agit donc pas de « revenir » à un autre état. L'application restera dans cet état "toujours provisoire" jusqu'à ce qu'il y ait un "accord" final (où l'utilisateur voit la deuxième alerte et accepte de passer à .authorizedAlways
ou refuse et il est défini sur .authorizedWhenInUse
).
Je sais que vous le savez, mais pour le bien des futurs lecteurs :
Dans la vidéo WWDC 2020 What's new in location , ils décrivent un changement introduit dans iOS 13.4. Au lieu du flux ci-dessus (où vous demandez "toujours", l'utilisateur voit les autorisations "lors de l'utilisation", et il ne voit pas la "mise à niveau vers toujours" jusqu'à ce que les services "toujours" soient réellement déclenchés), iOS 13.4 a introduit un nouveau flux, où vous pouvez demander "lors de l'utilisation" (plutôt que "toujours") et en supposant que l'utilisateur l'ait accordé, vous pouvez demander "toujours" plus tard, le cas échéant dans l'application, et l'utilisateur reçoit la deuxième alerte ( cette fois en demandant si l'utilisateur souhaite passer à "toujours" ou non). Vous avez juste besoin des chaînes d'autorisations appropriées.