Search code examples
iosswiftgoogle-mapsgmsmapview

Google Maps API (GMS) map doesn't show up


Im trying to make the map automatically follow the user (location) but somehow the app either it crashes (no error message) or the map doesn't show up when I start up the app. What have I done wrong?

I have tried without the locationManager func, and then it does work. Are there any other ways to follow the user?

    class GMSTestViewController: BaseViewController, GMSMapViewDelegate {

        @IBOutlet weak var mapView: GMSMapView!

        let locationManager = CLLocationManager()
        var manager:CLLocationManager!

        override func viewDidLoad() {
            super.viewDidLoad()

            //Setup Location Manager
            manager = CLLocationManager()
            manager.delegate = self
            manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
            manager.requestAlwaysAuthorization()
            manager.startUpdatingLocation()

            //Map type
            mapView.mapType = kGMSTypeTerrain
        }

        override func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            let userLocation = locations.last
            let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)

            let camera = GMSCameraPosition.cameraWithLatitude(userLocation!.coordinate.latitude,
                                                              longitude: userLocation!.coordinate.longitude, zoom: 8)
            let mapView = GMSMapView.mapWithFrame(.zero, camera: camera)
            mapView.myLocationEnabled = true
            self.view = mapView

            let marker = GMSMarker()
            marker.position = center
            marker.title = "Current Location"
            marker.snippet = "XXX"
            marker.map = mapView

            locationManager.stopUpdatingLocation()
        }

    }

It looks like this when I start it up, and then it keeps blinking with the map (on the users location).


Solution

  • I believe the best way to do it is to use key-value observing (KVO):

    override func viewWillAppear(animated: Bool) {
        mapView.addObserver(self, forKeyPath: "myLocation", options:0, context:nil)
    }
    
    deinit {
        mapView.removeObserver(self, forKeyPath:"myLocation", context:0)
    }
    
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if(keyPath! == "myLocation"]) {
            let location = [object myLocation]
    
            let target =
            CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude);
    
            mapView.animateToLocation(target)
            mapView.animateToZoom(17)
        }
    }