Search code examples
iosxcodegoogle-mapsswift4gmsmapview

App crashes when run more than once on GMSMAPVIEW


I have an app that finds places near the user’s location, however, the app crashes the second time it runs with the exception: fatal error: unexpectedly found nil while unwrapping an Optional value. On line: self.googleMapView.animate(toLocation: coordinates)

I checked and the googleMapView is nil but I don’t understand how it is nil or how it ran the first time. It only starts crashing on subsequent tries if I delete and reinstall the app it works fine on the first try but after that it keeps crashing even if I restart the app. Full code below

import UIKit
import GoogleMaps
import GooglePlacePicker
import MapKit

 class MapViewController: UIViewController, CLLocationManagerDelegate {
var currentLongitude: CLLocationDegrees = 0
var currentLatitude: CLLocationDegrees = 0
var locationManager: CLLocationManager!
var placePicker: GMSPlacePickerViewController!
var googleMapView: GMSMapView!

@IBOutlet weak var mapViewContainer: MKMapView!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.googleMapView = GMSMapView(frame: self.mapViewContainer.frame)
    self.googleMapView.animate(toZoom: 18.0)
    self.view.addSubview(googleMapView)
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.locationManager = CLLocationManager()
    self.locationManager.delegate = self
    self.locationManager.requestAlwaysAuthorization()
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let location:CLLocation = locations.last {
        self.currentLatitude = location.coordinate.latitude
        self.currentLongitude = location.coordinate.longitude
    }
    else {
        print("Location Error")
    }

    let coordinates = CLLocationCoordinate2DMake(self.currentLatitude, self.currentLongitude)
    let marker = GMSMarker(position: coordinates)
    marker.title = "I am here"
    marker.map = self.googleMapView
    self.googleMapView.animate(toLocation: coordinates)
}



private func locationManager(manager: CLLocationManager,
                     didFailWithError error: Error){
    print("An error occurred while tracking location changes : \(error.localizedDescription)")
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}


Solution

  • Crash is pretty self-explanatory:

    You are setting your location's delegate in the viewDidLoad but creating the map in the viewDidAppear.

    If the location was known by iOS, you will receive the message before viewDidAppear call so in the line : self.googleMapView.animate(toLocation: coordinates), your map is still nil

    You can either define your map as optional : var googleMapView: GMSMapView?, or you can wait for your map to be defined to create your location Manager.