Search code examples
iosswiftmapkitmkpointannotation

Why second MKPointAnnotation doesn't show?


I'am trying to show two annotations at MapView.

Why second annotation doesn't show in MapView? I have tried to change placemarks[0] to place marks[1] but with no help.

I could have used for clause but for testing i repeated the code.

class Asiakas {
    var nimi = ""
    var osoite = ""

    init(nimi: String, osoite: String) {
        self.nimi = nimi
        self.osoite = osoite
    }
}


class ViewController: UIViewController {

    @IBOutlet weak var mapView: MKMapView!

    var asiakkaat:[Asiakas] = [
        Asiakas(nimi: "Testi Asiakas", osoite: "Museokatu 10, helsinki"),
        Asiakas(nimi: "Hyvä asiakas", osoite: "Pihlajatie 17, helsinki")
    ]

    var asiakas:Asiakas!


    override func viewDidLoad() {
        super.viewDidLoad()

        let geoCoder = CLGeocoder()

        geoCoder.geocodeAddressString(asiakkaat[0].osoite, completionHandler: { placemarks, error in
            if error != nil {
                print(error)
                return
            }

            if let placemarks = placemarks {
                let placemark = placemarks[0]

                let annotation = MKPointAnnotation()
                if let location = placemark.location {
                    annotation.coordinate = location.coordinate
                    self.mapView.addAnnotation(annotation)
                }
            }
        })

        geoCoder.geocodeAddressString(asiakkaat[1].osoite, completionHandler: { placemarks, error in
            if error != nil {
                print(error)
                return
            }

            if let placemarks = placemarks {
                let placemark = placemarks[0]

                let annotation = MKPointAnnotation()
                if let location = placemark.location {
                    annotation.coordinate = location.coordinate
                    self.mapView.addAnnotation(annotation)
                }
            }
        })

    }

Solution

  • You can't make multiple simultaneous calls to geocode services.

    From the docs of geocodeAddressString(_ addressString: String, completionHandler: CoreLocation.CLGeocodeCompletionHandler):

    Submits a forward-geocoding request using the specified string. This method submits the specified location data to the geocoding server asynchronously and returns. Your completion handler block will be executed on the main thread. After initiating a forward-geocoding request, do not attempt to initiate another forward- or reverse-geocoding request.

    So you need to make the second call after the first one has been completed.

    If you do this you will get the correct results:

    let geoCoder = CLGeocoder()
    
    geoCoder.geocodeAddressString(asiakkaat[0].osoite, completionHandler: { placemarks, error in
        if error != nil {
            print(error)
            return
        }
    
        geoCoder.geocodeAddressString(self.asiakkaat[1].osoite, completionHandler: { placemarks, error in
            if error != nil {
                print(error)
                return
            }
    
            if let placemarks = placemarks {
                let placemark = placemarks[0]
    
                let annotation = MKPointAnnotation()
                if let location = placemark.location {
                    annotation.coordinate = location.coordinate
                    self.mapView.addAnnotation(annotation)
                }
            }
        })
    
        if let placemarks = placemarks {
            let placemark = placemarks[0]
    
            let annotation = MKPointAnnotation()
            if let location = placemark.location {
                annotation.coordinate = location.coordinate
                self.mapView.addAnnotation(annotation)
            }
        }
    })