Reputation: 105
i'm trying to get direction to the nearest pin from the user current location
-My Code is
let locationManager = CLLocationManager()
var currentCoordinate: CLLocationCoordinate2D!
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pins = mapView?.annotations
// let currentLocation = mapView?.userLocation.location
guard let currentLocation = locations.first else { return }
currentCoordinate = currentLocation.coordinate
let nearestPin: MKAnnotation? = pins!.reduce((CLLocationDistanceMax,nil)) { (nearest, pin) -> (CLLocationDistance, MKAnnotation) in
let coord = pin.coordinate
let loc = CLLocation(latitude: coord.latitude, longitude: coord.longitude)
let distance = currentLocation.distance(from: loc)
print(distance, pin)
return distance < nearest.0 ? (distance, pin) : nearest as! (CLLocationDistance, MKAnnotation)
} as AnyObject as? MKAnnotation
if nearestPin?.title == "Test"{
print("found")
}
}
but it's not working as well
thank you
Upvotes: 1
Views: 172
Reputation: 26
First of all, check if you have set the Location Privacy in your Info.plist
. In your case I check the authorization in an extension.
CLLocationManagerDelegate
extension ViewController: CLLocationManagerDelegate{
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
Don't forget to set the delegate in the viewDidLoad()
Delegate
locationManager.delegate = self
Now on to the actual question. I created a private function which can be called in
locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
Search nearest annotation
I guess you have an array of annotations declared (var annotation = [MKAnnotation]()
). We will use these annotations (in my case Paris and Amsterdam) compared to our current location to find the closest.
private func getNearestPin(locations: [CLLocation]) -> MKAnnotation? {
let allPinsOnMap = mapView?.annotations
guard let currentLocation = locations.first else { return nil }
if let pins = allPinsOnMap {
let nearestPin: (CLLocationDistance, MKAnnotation?) = pins.reduce((CLLocationDistanceMax,nil))
{ (nearest, pin) -> (CLLocationDistance, MKAnnotation?) in
let coord = pin.coordinate
let loc = CLLocation(latitude: coord.latitude, longitude: coord.longitude)
let distance = currentLocation.distance(from: loc)
return distance < nearest.0 ? (distance, pin) : nearest
}
return nearestPin.1
}
return nil
}
The function will return an MKAnnotation?
so when we call the function, we have to check if it doesn't return nil. We call this function in our extension!
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let nearest = getNearestPin(locations: locations) {
if nearest.title == "Amsterdam" {
print("Nearest is available: \(nearest.title! ?? "Title")")
}
}
}
If you have any further questions or feedback, please let me know!
Upvotes: 1