Reputation: 109
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)
Upvotes: 0
Views: 77
Reputation: 54706
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.
Upvotes: 0
Reputation: 23
Based on the output, I'm not seeing this line being outputted:
print("distance is \(distance)")
This leads me to believe that your distances are not being appended to the calculations array.
So because of that, the calculations array is empty at the end of your while loop and when you try to get the min() of an empty array, it will return nil and force unwrapping that will cause the crash.
I would recommend you put a breakpoint on the line where you're appending the distance to the calculations array and see if it's being executed.
If it is, then try printing out values of the calculations array at the end of the while loop and see if there are still values in it at that point.
Upvotes: 0