Erva Erva - 15 days ago 6
iOS Question

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)
}
}
})

}

Answer

You can't make multiple simultaneos 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)
        }
    }
})