Alec Alec - 1 year ago 86
Swift Question

Swift - fatal error: unexpectedly found nil while unwrapping an Optional value on MKCoordinateRegionMakeWithDistance

I'm trying to get my map to show directions to a local searched location from the current user location.

I'm getting an EXC_BAD_INSTRUCTION on the line:

let region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 2000, 2000)`

And on the line:

else {

I have a feeling the nil it's receiving is from the user location, which I'm not sure why it would be receiving a nil there.

Here is the full code for my view controller if needed:

class RouteViewController: UIViewController, MKMapViewDelegate {

@IBOutlet weak var routeMap: MKMapView!

var destination = MKMapItem?()

override func viewDidLoad() {

routeMap.showsUserLocation = true
routeMap.delegate = self

func getDirections() {

let request = MKDirectionsRequest()
request.requestsAlternateRoutes = false

let directions = MKDirections(request: request)

MKDirectionsResponse!, error: NSError!) in

if error != nil {
println("Error getting directions")
} else {


func showRoute(response: MKDirectionsResponse) {

for route in response.routes as! [MKRoute] {

level: MKOverlayLevel.AboveRoads)

for step in route.steps {
let userLocation = routeMap.userLocation
let region = MKCoordinateRegionMakeWithDistance(
userLocation.location.coordinate, 2000, 2000)

routeMap.setRegion(region, animated: true)

func mapView(mapView: MKMapView!, rendererForOverlay
overlay: MKOverlay!) -> MKOverlayRenderer! {
let renderer = MKPolylineRenderer(overlay: overlay)

renderer.strokeColor = UIColor.blueColor()
renderer.lineWidth = 5.0
return renderer


And the segue code:

override func prepareForSegue(segue: UIStoryboardSegue,
sender: AnyObject?) {
let routeViewController = segue.destinationViewController
as! RouteViewController

let indexPath = self.tableView.indexPathForSelectedRow()

let row = indexPath?.row

routeViewController.destination = mapItems[row!]

Any help would be appreciated, thanks!

Answer Source

The problem is this line:

let userLocation = routeMap.userLocation

The result, userLocation might be nil, and its location might be nil, because the map might not have been told to, or succeeded in acquiring, the user's location. You are not taking into account that possibility.

The way to do that is to unwrap the Optionals safely and proceed only if the unwrapping succeeded:

if let userLocation = routeMap.userLocation, loc = userLocation.location {
    let region = MKCoordinateRegionMakeWithDistance(
        loc.coordinate, 2000, 2000)
    routeMap.setRegion(region, animated: true)

We don't need the userLocation separately for anything, so we can collapse that into a single test:

if let loc = routeMap.userLocation.location {
    let region = MKCoordinateRegionMakeWithDistance(
        loc.coordinate, 2000, 2000)
    routeMap.setRegion(region, animated: true)