mapItem.openInMaps Unknown Location

Hello,

I've implemented directions to my annotations on map. But when Apple Maps are opening I can only see Uknown Location as a destination point. What I would like to do is to have Annotation title instead of Unknown Location. Here is my code:

class AnnotationButton: UIButton {

    var annotation: MKPointAnnotation?

}

    func findPlace(_ places: [Place]) {

      for place in places {

        let annotations = MKPointAnnotation()

        annotations.title = place.name

        annotations.subtitle = place.description

        annotations.coordinate = CLLocationCoordinate2D(latitude:

          place.lattitude, longitude: place.longtitude)

        mapView.addAnnotation(annotations)

      }

    }
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        guard !(annotation is MKUserLocation) else { return nil }

        let identifier = "identifier"

        guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MKMarkerAnnotationView else { return nil }


let leftButton = AnnotationButton(frame: CGRect(

          origin: CGPoint.zero,

          size: CGSize(width: 25, height: 25)))

        leftButton.setBackgroundImage(#imageLiteral(resourceName: "nav"), for: .normal)

        annotationView.leftCalloutAccessoryView = leftButton

        leftButton.addTarget(self, action: #selector(didClickDetailDisclosureNavigation(button:)), for: .touchUpInside)

        if let pointAnnotation = annotation as? MKPointAnnotation {

                    leftButton.annotation = pointAnnotation

                }

    @objc func didClickDetailDisclosureNavigation(button: AnnotationButton) {

            let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]

            if let mapItem = button.annotation?.mapItem {

                    mapItem.openInMaps(launchOptions: launchOptions)

    }

    }

extension MKPointAnnotation {

    var mapItem: MKMapItem {

        let placemark = MKPlacemark(coordinate: self.coordinate)

        return MKMapItem(placemark: placemark)

    }

}
Answered by Claude31 in 694017022

Effectively, self is MKPointAnnotation

So, just change as:

        mapItem.name = self.title 

Likely the coordinates are not recognised as a specific location.

Try this:

class AnnotationButton: UIButton {

    var annotation: MKPointAnnotation?

    var mapItem: MKMapItem {
        let placemark = MKPlacemark(coordinate: self.coordinate) // You do not show full class, so I hope self points to the right object
        let mapItem = MKMapItem(placemark: placemark)
        mapItem.name = annotation?.title ?? "unknown" // Provide the name of the destination in the To: field

        return mapItem
    }

}

Note: Having the extension far away from class definition makes it harder to read. I personally prefer, for such a simple class, to include the extension inside.

When you post code, please use Paste and Match Style to avoid all the extra blank lines.

@Claude31 Sorry, I think I misled you. I did not added the main class to the question. Thats why your code can't work that way. Here is the correct code:

class AnnotationButton: UIButton {

    var annotation: MKPointAnnotation?

}

class ViewController: UIViewController, MKMapViewDelegate {

    func findPlace(_ places: [Place]) {

      for place in places {

        let annotations = MKPointAnnotation()

        annotations.title = place.name

        annotations.subtitle = place.description

        annotations.coordinate = CLLocationCoordinate2D(latitude:

          place.lattitude, longitude: place.longtitude)

        mapView.addAnnotation(annotations)

      }

    }
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        guard !(annotation is MKUserLocation) else { return nil }

        let identifier = "identifier"

        guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MKMarkerAnnotationView else { return nil }


let leftButton = AnnotationButton(frame: CGRect(

          origin: CGPoint.zero,

          size: CGSize(width: 25, height: 25)))

        leftButton.setBackgroundImage(#imageLiteral(resourceName: "nav"), for: .normal)

        annotationView.leftCalloutAccessoryView = leftButton

        leftButton.addTarget(self, action: #selector(didClickDetailDisclosureNavigation(button:)), for: .touchUpInside)

        if let pointAnnotation = annotation as? MKPointAnnotation {

                    leftButton.annotation = pointAnnotation

                }

    @objc func didClickDetailDisclosureNavigation(button: AnnotationButton) {

            let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]

            if let mapItem = button.annotation?.mapItem {

                    mapItem.openInMaps(launchOptions: launchOptions)
    }

    }

extension MKPointAnnotation {

    var mapItem: MKMapItem {

        let placemark = MKPlacemark(coordinate: self.coordinate)

        return MKMapItem(placemark: placemark)

    }
}

Well, if you prefer a class extension, you can do it that way:

extension MKPointAnnotation {
    var mapItem: MKMapItem {
        let placemark = MKPlacemark(coordinate: self.coordinate) 
        let mapItem = MKMapItem(placemark: placemark)
        mapItem.name = self.annotation?.title ?? "unknown" // Provide the name of the destination in the To: field

        return mapItem
    }
}
Accepted Answer

Effectively, self is MKPointAnnotation

So, just change as:

        mapItem.name = self.title 
mapItem.openInMaps Unknown Location
 
 
Q