0

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

    }
Erva
  • 47
  • 8

1 Answers1

0

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)
        }
    }
})
Otávio
  • 735
  • 11
  • 23
  • Ok, thanks for your answer. I might put geoCode to it's own function and call it from viewDidLoad function. There gonna be about 100 annotations. – Erva Nov 24 '16 at 22:01
  • @Erva be aware that the geocode has a rate limit. From the docs `Applications should be conscious of how they use geocoding. Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail. (When the maximum rate is exceeded, the geocoder returns an error object with the value network to the associated completion handler.) ` – Otávio Nov 25 '16 at 11:45
  • I already tested with about 100 address in for clause. Geocode didn't resolve about 1/5 of addresses. This explains why. I thought geocode didn't "know" addresses, but probably it's because rate-limit. Completion handler didn't give any error messages. – Erva Nov 25 '16 at 12:14