iOS swift MapKit, pins added from search callback handler not appearing on the map

366 views Asked by At

so i've been learning iOS, and for my practice for MapKit, i have made an app that zooms in on my region and puts a pin at my location (geo coordinates given to the simulator), that all seems to be working and i can even see the pin...

But next i am doing a search for nearby shops with 'Shop' keyword and printing out the names of the search item in the callback handler seem to be showing them. But the pins for that arent appearing on the map.

I googled some, the mapView(mapView:viewFor:)->MKAnnotation doesnt seem to be a lazy function which has to dequeue and make new MKPinAnnotationView objects and return them.... The reason why i checked for lazy is if i print the names of each pin to be returned from inside it doesnt show anything printed, but if i put a breakpoint in there, it will show it then...

Other than that, at first couple of times the pins were showing, so i know the code for adding them is working, but then i added titles to each pin, now i dont know if its taking long to search them and the app finishes its work till then or something or not...

important bits from the code:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    locationManager.delegate = self
    mapView.delegate = self

    if CLLocationManager.authorizationStatus() == .notDetermined {
        self.locationManager.requestWhenInUseAuthorization()
    }

    locationManager.distanceFilter = kCLDistanceFilterNone
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()

}


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    manager.stopUpdatingLocation()
    locationManager.delegate = nil
    centerMapOnLocation(location: manager.location!)

    // Searching for shops
    let request = MKLocalSearchRequest()
    request.naturalLanguageQuery = "Shop"
    request.region = mapView.region

    let search = MKLocalSearch(request: request)

    search.start(completionHandler: {(response, error) in
        if error != nil {
            print("Error occured in search: \(error!.localizedDescription)")
        } else if response!.mapItems.count == 0 {
            print("No matches found")
        } else {
            print("Matches found")

            for item in response!.mapItems {
                let shopPin = MKPointAnnotation()
                shopPin.coordinate = item.placemark.coordinate
                shopPin.title = item.name
                self.mapView.addAnnotation(shopPin)
                print("Name = \(item.name!)")
                //print(shopPin.title)
            }
                        }
    })



    // Putting a pin on current location
    let homePin = MKPointAnnotation()
    homePin.coordinate = (manager.location?.coordinate)!
    homePin.title = "BitSol Technologies"
    mapView.addAnnotation(homePin)

}


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

    let pinIdent = "Pin";
    var pinView: MKPinAnnotationView;
    if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: pinIdent) as? MKPinAnnotationView {
        dequeuedView.annotation = annotation;
        pinView = dequeuedView;
    }else{
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pinIdent);
    }
    if annotation.coordinate.latitude == locationManager.location!.coordinate.latitude &&  annotation.coordinate.longitude == locationManager.location!.coordinate.longitude{
        pinView.pinTintColor = MKPinAnnotationView.redPinColor();
    }else{
        pinView.pinTintColor = MKPinAnnotationView.purplePinColor()
    }
    pinView.canShowCallout = true
    print(annotation.title!)
    return pinView;
}
2

There are 2 answers

1
Kosuke Ogawa On

Perhaps MKLocalSearch completion handler doesn't run on main thread. Try the following code:

    let search = MKLocalSearch(request: request)
    search.start(completionHandler: {(response, error) in
        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if error != nil {
                print("Error occured in search: \(error!.localizedDescription)")
            } else if response!.mapItems.count == 0 {
                print("No matches found")
            } else {
                print("Matches found")

                for item in response!.mapItems {
                    let shopPin = MKPointAnnotation()
                    shopPin.coordinate = item.placemark.coordinate
                    shopPin.title = item.name
                    self.mapView.addAnnotation(shopPin)
                    print("Name = \(item.name!)")
                    //print(shopPin.title)
                }
            }
        }
    })
2
AshokPolu On

Call this line of code after adding all annotations on map,

self.mapView.showAnnotations(self.mapView.annotations, animated: true)