Emplacement actuel ne fonctionne pas dans Google Map

J'ai embedded google map dans swift 3, quand l'écran de carte apparaît à l'endroit actuel en ne montrant pas, j'ai ajouté deux clefs dans le file .plist et ai également placé le délégué de CLLocationManager et le requestAlwaysAuthorization

class MapViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate { @IBOutlet var mapView: GMSMapView! var marker: GMSMarker? override func viewDidLoad() { super.viewDidLoad() self.title = "MapVC" self.doSetupUI() self.searchLocation() } override func viewWillAppear(_ animated: Bool) { let locationManager : CLLocationManager = CLLocationManager() locationManager.delegate = self locationManager.requestAlwaysAuthorization() } func doGoogleMapSetup(lat : Double , lng : Double) { let camera = GMSCameraPosition.camera(withLatitude: lat, longitude:lng, zoom:16) let mapView = GMSMapView.map(withFrame: .zero, camera:camera) mapView.isMyLocationEnabled = true let marker = GMSMarker() marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lng) marker.snippet = "" marker.appearAnimation = kGMSMarkerAnimationPop marker.map = mapView let arrPoints : NSMutableArray = NSMutableArray() arrPoints.add(UserDefaults.standard.object(forKey: "addressPoints")) for i in 0..<arrPoints.count { let path : Ssortingng = (arrPoints.object(at: i)as! NSMutableArray).object(at: 0) as! Ssortingng let route : GMSPath = GMSPath.init(fromEncodedPath: path)! let polyLine : GMSPolyline = GMSPolyline.init(path: route) polyLine.strokeWidth = 2.0 polyLine.strokeColor = UIColor.red polyLine.map = mapView } } 

Pour afficher l'location actuel, nous n'avons pas besoin de gestionnaire de localization dans le cas de GoogleMaps . Tout ce dont nous avons besoin est d'append une des keys ou les deux dans le file .plist . Alors assurez-vous que la key est là. J'ai utilisé la key NSLocationWhenInUseUsageDescription .

 <key>NSLocationWhenInUseUsageDescription</key> <ssortingng>Allow location</ssortingng> 

entrez la description de l'image ici

Assurez-vous également que vous avez appelé GMSServices et que vous avez provideAPIKey méthode provideAPIKey par l' API_KEY que vous avez générée dans la console google developer. Toutes les API Google pertinentes selon les exigences doivent également être activées.

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. GMSServices.provideAPIKey("YOUR_API_KEY") return true } 

Donc, je suppose que vous avez fait tous les parameters et les choses bien dans la console de développeur google.

En écrivant juste la ligne ci-dessous dans votre controller où vous avez fait le GoogleMap peut montrer l'invite d'autorisation / interdiction de localization et prendre la permission de l'user.

 mapView.isMyLocationEnabled = true 

Cependant, cela n'animera pas votre carte à votre location actuel. Mais vous pouvez faire glisser la carte manuellement pour vérifier l'location actuel et vous verrez un point bleu à votre location actuel.

Mais maintenant, nous voulons aussi animer à l'location actuel chaque fois que nous chargeons ce ViewController . Maintenant, le besoin de CLLocationManager arrive. Ainsi, dans son délégué didUpdateLocation , nous pouvons aller chercher l'location actuel et simplement animer le graphique à l'location actuel.

Alors voici mon controller complet.

 import UIKit import GoogleMaps class ViewController: UIViewController,GMSMapViewDelegate,CLLocationManagerDelegate { @IBOutlet weak var mapView: GMSMapView! var locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() mapView.isMyLocationEnabled = true mapView.delegate = self //Location Manager code to fetch current location self.locationManager.delegate = self self.locationManager.startUpdatingLocation() } //Location Manager delegates func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude:(location?.coordinate.longitude)!, zoom:14) mapView.animate(to: camera) //Finally stop updating location otherwise it will come again and again in this delegate self.locationManager.stopUpdatingLocation() } } 

Une autre méthode consiste à ne pas utiliser didUpdateLocation et de ne pas utiliser le gestionnaire d'location simplement en utilisant la méthode déléguée mapViewDidFinishTileRendering

 func mapViewDidFinishTileRendering(_ mapView: GMSMapView) { let location = mapView.myLocation let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude:(location?.coordinate.longitude)!, zoom:14) mapView.animate(to: camera) } 

Il sera appelé à chaque fois que le rendu de la carte est terminé.
Mais cela vient avec une limitation, il vous amènera toujours à l'location actuel chaque fois que vous faites glisser / pincer / zoomer la carte que le rendu se termine chaque fois que vous jouez avec la carte. Donc, vous pouvez simplement implémenter une sorte de logique bool ici.

Vous pouvez get votre position en utilisant

 let yourCurrentLocation = mapView.myLocation 

Assurez-vous de le faire sur un appareil plutôt que sur un simulateur. Si vous utilisez un simulateur, vous devez choisir un location personnalisé et vous seul pourrez voir le point bleu.

entrez la description de l'image ici

J'ai déjà donné ce type de réponse. Vérifiez ce lien . Mais c'était dans Swift 2.x. Celui que j'ai posté dans cette réponse est dans Swift 3.x

C'est un peu détaillé, alors j'aimerais le laisser dans une réponse complète. C'est la raison la plus commune que j'ai rencontrée pour un endroit nul, depuis que j'ai compris les bases, il y a quelques années. Ainsi, vous appelez CLLocationManager.startLocating (), dans votre viewDidLoad. Ensuite, vous appelez la méthode qui configure votre carte. Parfois, cela fonctionne, et parfois non, en raison d'une condition de concurrency causée par le time nécessaire à CLLocationManager pour configurer les permissions, d'une part, et accéder à l'location de l'user, dans une autre partie du code. Regardons un ordre d'events, où cela ne fonctionne pas:

1) vous appelez requestAlwaysAuthroization et startLocating 2) La configuration des permissions user est déclenchée sur un thread 3) Dans votre ViewController, vous requestz l'location de l'user, pour configurer votre map 4) Il revient nil 5) MAINTENANT, l'étape 2 se termine, et application a access à l'location de l'user, mais il est trop tard

Le problème principal, c'est que le process qui commence par requestr des permissions et l'location prend plus de quelques millisecondes. Et si votre vue est déjà configurée, il lui faut quelques millisecondes pour passer en revue les methods de votre viewDidLoad. Au moment où vous avez l'location dont vous avez besoin, vous l'avez déjà demandé. Cela m'a causé trop de plantages, dans mes applications basées sur la localization.

Ma solution de contournement a consisté à créer un CLLocationManager singleton, à faire de ma vue de départ un délégué, et à requestAlwaysAuthorization et startLocating, dans cette vue. De cette façon, lorsque j'arrive à la vue qui a besoin de l'location, l'application a déjà commencé à se localiser et la location location.location n'est pas nulle.

C'est une approche qui ne fonctionnera évidemment pas pour toutes les applications. Si vous avez besoin de clarification, faites-le moi savoir, et si vous avez besoin de code, aussi. J'ai quelques repos iO git publics, avec des projets où j'ai rencontré et résolu ce problème.