Reputation: 305
I'm trying to integrate a styled Google Map into my iOS app that I'm programming in Swift. I have a view in my storyboard that is a GMSMapView, and I'm trying to color it with custom JSON. Here is the code for making the mapView:
@IBOutlet weak var mapView: GMSMapView!
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.camera(withLatitude: userLocation!.coordinate.latitude,
longitude: userLocation!.coordinate.longitude, zoom: 13.0)
mapView.isMyLocationEnabled = true
mapView.camera = camera
self.view = mapView
locationManager.stopUpdatingLocation()
}
override func loadView() {
do {
// Set the map style by passing the URL of the local file.
if let styleURL = Bundle.main.url(forResource: "style", withExtension: "json") {
***error-> self.mapView.mapStyle = try GMSMapStyle(contentsOfFileURL: styleURL)
} else {
NSLog("Unable to find style.json")
}
} catch {
NSLog("One or more of the map styles failed to load. \(error)")
}
}
but when I try to run it, I get a fatal error:
unexpectedly found nil while unwrapping an Optional value
The line that throws the error is the one with the ***
on it. I've linked the GMSMapView with the View on the storyboard, and the app compiles correctly without trying to style it. Does anyone know why this error is occurring? I've Googled the error but couldnt find anything that relates to my code, and I couldn't understand what some of the links wanted me to do.
Upvotes: 0
Views: 1457
Reputation: 318774
The error is because self.mapView
is nil
. Here's why:
Your map view is setup as an outlet to your storyboard. In this case, your map view will be created for you. Just make sure the map view is actually connected to the outlet.
The real issue is that you have overloaded the loadView
method. Don't do that. From the docs for UIViewController loadView
:
If you use Interface Builder to create your views and initialize the view controller, you must not override this method.
The code you currently have in loadView
should be moved to the viewDidLoad
method.
override func viewDidLoad() {
super.viewDidLoad()
do {
// Set the map style by passing the URL of the local file.
if let styleURL = Bundle.main.url(forResource: "style", withExtension: "json") {
self.mapView.mapStyle = try GMSMapStyle(contentsOfFileURL: styleURL)
} else {
NSLog("Unable to find style.json")
}
} catch {
NSLog("One or more of the map styles failed to load. \(error)")
}
// and any other code you might need in viewDidLoad
}
The next big issue is that you assign a value to self.view
inside the location manager delegate. That's bad too. The only place you should ever assign something to self.view
in a view controller is in loadView
and only if you are creating the whole view controller and its view programmatically.
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.camera(withLatitude: userLocation!.coordinate.latitude,
longitude: userLocation!.coordinate.longitude, zoom: 13.0)
mapView.isMyLocationEnabled = true
mapView.camera = camera
locationManager.stopUpdatingLocation()
}
Summary:
loadView
method. Move its contents to viewDidLoad
self.view
any where in your code.Upvotes: 2