Search code examples
swiftif-statementfatal-erroroptional-valuesmkdirection

Swift Direction Request does not calculate in if statement correctly


I wanted to calculate distances from users current location to many different location and put these calculations into calculations array. So I can sort this array and find the closest location. At the end I want to show the closest location on the top of the table view for user experience. But I can not append each calculations into "calculations array" correctly. Please see outputs I am getting with print() at the end of my codes. Where am I doing wrong? Thanks for your helps.

   override func viewDidLoad() {
    super.viewDidLoad()
    visualEffect.isHidden = true

    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestWhenInUseAuthorization()
    manager.startUpdatingLocation()

    Calculate()
}

var closestDistanceIndex:Int = 0

func Calculate()  {


// anlık lokasyona en yakın giriş hesaplaması

    var calculations:[Double] = []
    var distance:Double = 0.0
    var i = 1

    while i < (giselerGiris.count)
    {
        print("index \(i)")

        let locValue:CLLocationCoordinate2D = manager.location!.coordinate

        let source1 = MKMapItem( placemark: MKPlacemark(
            coordinate: CLLocationCoordinate2DMake(locValue.latitude, locValue.longitude),
            addressDictionary: nil))

        let destination1 = MKMapItem(placemark: MKPlacemark(
            coordinate: CLLocationCoordinate2DMake(girisLatitude[i], girisLongtitude[i]),
            addressDictionary: nil))

        let directionsRequest = MKDirectionsRequest()
        directionsRequest.source = source1
        directionsRequest.destination = destination1
        directionsRequest.transportType = .automobile


        let directions = MKDirections(request: directionsRequest)

        directions.calculate { (response, error) -> Void in
            print("hata \(String(describing: error))")
            distance = (response!.routes.first?.distance)!

            print("distance is \(distance)")
            calculations.append(distance)
        }

        print("distance \(i): \(distance)")
         i += 1
    }

    let closestDistance = calculations.min()!
    print("closest distance is \(closestDistance)")
    closestDistanceIndex = calculations.index(of: closestDistance)!   
    print("closest distance index is  \(closestDistanceIndex)")
}

I am getting below error

 fatal error: unexpectedly found nil while unwrapping an Optional value
 (lldb)

in this row

  let closestDistance = calculations.min()!

and here are outputs

index 1
distance 1: 0.0
index 2
distance 2: 0.0
index 3
distance 3: 0.0
index 4
distance 4: 0.0
index 5
distance 5: 0.0
index 6
distance 6: 0.0
index 7
distance 7: 0.0
index 8
distance 8: 0.0
index 9
distance 9: 0.0
index 10
distance 10: 0.0
index 11
distance 11: 0.0
index 12
distance 12: 0.0
index 13
distance 13: 0.0
index 14
distance 14: 0.0
index 15
distance 15: 0.0
index 16
distance 16: 0.0
index 17
distance 17: 0.0
index 18
distance 18: 0.0
index 19
distance 19: 0.0
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) 

Solution

  • The problem is that directions.request is an asynchronous method since it needs to call Apple's server to calculate the distance and you are trying to use its values before the requests could actually return. Also be aware that there is a rate limit on most MapKit calls that require a network request, so if you make 20calls in a row, you might get rate limited (even though Apple doesn't publish its exact numbers, so you don't know when exactly this happens).

    You need to wait for all of your direction requests to finish execution before using their values. Array.min() returns nil if the array is empty, which is the case here and hence the error.