J'ai ce code:
import UIKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate { let locationManager = CLLocationManager() override func viewDidLoad() { self.locationManager.requestWhenInUseAuthorization() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters super.viewDidLoad() } @IBAction func sendLocation() { locationManager.startUpdatingLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let coordinate = locations.last?.coordinate else { return } print(String(coordinate.latitude)) locationManager.stopUpdatingLocation() } }
Lors du cliquetis sur le UIButton
, IBAction
est appelé et l'emplacement actuel des utilisateurs est affiché dans la console.
Comme je n'ai besoin d'obtenir l'emplacement qu'une seule fois, je voudrais utiliser locationManager.requestLocation()
.
Mais lors de la suppression de locationManager.stopUpdatingLocation () et en remplaçant locationManager.startUpdatingLocation ()
par locationManager.requestLocation ()
, l'application plante en appuyant sur le UIButton avec les journaux suivants dans la console:
2019-01-09 15: 48: 36.585518 + 0100 GetLocation [1206: 248754] *** Assertion échec dans - [CLLocationManager requestLocation], /BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreLocationFramework/CoreLocation-2245.8.25/Framework/CoreLocation/CLLocationManager.m:897
09/01/2019 15: 48: 36.586443 + 0100 GetLocation [1206: 248754] *** Arrêt de l'application en raison d'une exception non interceptée 'NSInternalInconsistencyException', raison: 'Le délégué doit répondre à locationManager: didFailWithError: '
*** Première pile d'appels lancée:
(0x1b4e08ec4 0x1b3fd9a50 0x1b4d1eb3c 0x1b580d1d0 0x1bbcd8280 0x104690028 0x10469005c 0x1e20f23f8 0x1e1b7ffb8 0x1e1b802d8 0x1e1b7f2d8 0x1e212bb50 0x1e212cdb4 0x1e210c0b0 0x1e21daf1c 0x1e21dd914 0x1e21d6404 0x1b4d991f0 0x1b4d99170 0x1b4d98a54 0x1b4d93920 0x1b4d931f0 0x1b700c584 0x1e20f0ce4 0x104691564 0x1b4852bb4)
libc ++ abi.dylib: se terminant avec une exception non interceptée de type NSException
(lldb)
Pourquoi cela? Qu'est-ce que je fais de mal?
3 Réponses :
Vous devrez peut-être implémenter la méthode
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { --- }
Delegate de CLLocationManagerDelegate
Cela évite de planter mais l'emplacement n'est pas non plus affiché dans la console. Une idée pourquoi?
appelez sendLocation
dans viewDidLoad
Oui, j'appelle func sendLocation ()
en cliquant sur un UIButton
.
également locationManager.startUpdatingLocation ()
Attendez, je vais réécrire ma question…
J'ai implémenté func locationManager (_ manager: CLLocationManager, didFailWithError error: Error) {}
maintenant et il ne plante plus. locationManager.requestLocation ()
semble fonctionner mais il y a un délai de 10 secondes entre l'appui sur le UIButton
et l'emplacement affiché dans la console. Une idée pourquoi?
le processus n'est pas synchrone, il devrait y en avoir selon le gps voir ici développeur .apple.com / documentation / corelocation /…
vous pouvez modifier la précision souhaitée
Le message d'erreur est assez clair. Vous devez implémenter l'autre méthode déléguée, locationManager (_ :, didFailWithError :)
.
class ViewController: UIViewController, CLLocationManagerDelegate { let locationManager = CLLocationManager() override func viewDidLoad() { self.locationManager.requestWhenInUseAuthorization() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters super.viewDidLoad() } @IBAction func sendLocation() { locationManager.requestLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let coordinate = locations.last?.coordinate else { return } print(String(coordinate.latitude)) } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { // handle the error } }
Cela évite les plantages, mais l'emplacement n'est pas non plus affiché dans la console. Une idée pourquoi?
@David parce que la mise à jour de l'emplacement échoue et que func locationManager (_ manager: CLLocationManager, didFailWithError error: Error)
est appelé, mais vous n'affichez pas ou ne gérez pas l'erreur. C'est pourquoi vous avez également eu le crash, la fonction didFailWithError
était appelée, mais elle n'a pas été implémentée
J'ai implémenté func locationManager (_ manager: CLLocationManager, didFailWithError error: Error) {}
maintenant et il ne plante plus. locationManager.requestLocation ()
semble fonctionner mais il y a un délai de 10 secondes entre l'appui sur le UIButton
et l'emplacement affiché dans la console. Une idée pourquoi?
@David comme je l'ai déjà expliqué sur votre autre question, les mises à jour de localisation sont reçues de manière asynchrone (ce qui signifie qu'il y a un retard), en raison du fait que le GPS ne peut pas mettre à jour votre position instantanément
Je comprends cela maintenant. Mais pourquoi locationManager.startUpdatingLocation ()
fonctionne-t-il immédiatement?
@David cela ne fonctionne certainement pas immédiatement. C'est juste le fait que vous l'appeliez plusieurs fois, donc au deuxième essai, il a affiché la valeur précédemment récupérée (et retardée)
La raison est clairement décrite.
raison: 'Le délégué doit répondre à locationManager: didFailWithError:'
Vous devez implémenter
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { }
Comme l'emplacement de la demande se déroule de manière asynchrone, cela prendra du temps.
Lorsque l'emplacement est avec Location Manager, il informe l'utilisateur via locationManager:didUpdateLocations:
Vous testez cela dans le simulateur?
@Scriptable Non, je ne le fais pas. Je teste sur un vrai appareil.