Implémenter les méthodes CLLocationManagerDelegate dans Swift
-
21-12-2019 - |
Question
J'essaie de faire fonctionner cela depuis un certain temps maintenant, et je suis venu ici pour demander : comment puis-je utiliser les méthodes CLLocationManagerDelegate dans Swift ?J'ai mis ceci en tête de ma classe :
var locationManager = CLLocationManager()
J'ai mis ce qui suit dans mon viewDidLoad
méthode:
locationManager.delegate = self
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
Et j'ai essayé d'utiliser ces méthodes déléguées sans succès :
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
locationReceived = true
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationReceived = false
}
J'ai également essayé d'utiliser @optional devant les fonctions, mais Xcode renvoie alors une erreur du compilateur.Des idées?
La solution
Vous devez ajouter le NSLocationAlwaysUsageDescription
ou NSLocationWhenInUseUsageDescription
clé de votre plist si ce n'est pas déjà fait, ils sont désormais obligatoires,
iOS8+ nécessite que l'une de ces deux chaînes soit définie pour utiliser les emplacements.Celui que vous utilisez dépend de la manière dont vous comptez demander l’emplacement.
Utiliser
NSLocationAlwaysUsageDescription
pour les applications qui souhaitent utiliser la localisation de l'appareil même lorsque l'application n'est pas ouverte et en cours d'utilisation.Utiliser
NSLocationWhenInUseUsageDescription
pour les applications qui souhaitent utiliser la localisation de l'appareil uniquement lorsque l'application est ouverte et en cours d'utilisation.
Note: Lorsque vous ajoutez les chaînes, avant de créer et d'exécuter, supprimez l'application de votre appareil et laissez-la effectuer une nouvelle installation.Il semble que si l'application était autorisée à utiliser des emplacements avant la mise à niveau vers iOS8, elle ne vous demandera plus votre autorisation et ne verra pas que vous avez défini ces chaînes.Effectuer une suppression et une installation propre résout ce problème.
La définition de l'une ou l'autre des chaînes provoque une fenêtre contextuelle lors de l'installation/première utilisation du type :"Autorisez "ThisApp" à accéder à votre position même lorsque vous n'utilisez pas l'application"
Voici un Capture d'écran de la liste de plis déposer.
Autres conseils
Ajoutez d’abord ces deux lignes dans le fichier plist
1) NSLocationWhenInUseUsageDescription
2) NSLocationAlwaysUsageDescription
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
}
func initLocationManager() {
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationManager.stopUpdatingLocation()
if (error) {
if (seenError == false) {
seenError = true
print(error)
}
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
if (locationFixAchieved == false) {
locationFixAchieved = true
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as CLLocation
var coord = locationObj.coordinate
println(coord.latitude)
println(coord.longitude)
}
}
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus) {
var shouldIAllow = false
switch status {
case CLAuthorizationStatus.Restricted:
locationStatus = "Restricted Access to location"
case CLAuthorizationStatus.Denied:
locationStatus = "User denied access to location"
case CLAuthorizationStatus.NotDetermined:
locationStatus = "Status not determined"
default:
locationStatus = "Allowed to location Access"
shouldIAllow = true
}
NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil)
if (shouldIAllow == true) {
NSLog("Location to Allowed")
// Start location services
locationManager.startUpdatingLocation()
} else {
NSLog("Denied access: \(locationStatus)")
}
}
Pour obtenir l'emplacement actuel de l'utilisateur : -
Étape 1: let locationManager = CLLocationManager() // make object of CLLocationManager class.
Étape 2: In viewDidLoad instantiate the CLLocationManager class like,
// À utiliser en arrière-plan
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if (CLLocationManager.locationServicesEnabled())
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
Étape 3: Implémentez maintenant les méthodes déléguées de CLLocationManager
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue:CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(locValue.latitude) \(locValue.longitude)")
}
Étape 4:N'oubliez pas d'ajouter NSLocationAlwaysUsageDescription
dans l'Info.plist comme dans iOS 8 il est obligatoire de l'ajouter.Cela demandera l'autorisation d'utiliser la position de l'utilisateur.
J'ai eu le même problème.didUpdateLocations - ne fonctionnait pas.Exécutez votre application.Accédez à la page Paramètres -> Confidentialité -> Localisation et désactivez les services de localisation.didFailWithError détectera l’erreur concernant les services de localisation absents.Ensuite, allumez-le.À partir de ce moment, didUpdateLocations capturera les emplacements.
C'est un fil de discussion un peu ancien, mais aucun des éléments ci-dessus n'a fonctionné pour moi sur Swift 2.2 xCode 7.3.1.
Le problème c'est que j'utilisais :
func locationManager(manager: CLLocationManager!, didUpdateLocation locations: [AnyObject]!) {
print("Got location")
locationManager.stopUpdatingLocation()
}
Et cela n’a jamais été annoncé.Quand j'ai changé pour :
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Got location")
locationManager.stopUpdatingLocation()
}
Tout a fonctionné.On dirait que le délégué n'est pas appelé lors de l'utilisation de [AnyObject]