How to implement auto-complete for address using Apple Map Kit

I want to auto-complete the address for the user as same as what google api provides in this link:

  • iOS 6 Saving/Restoring app state feature
  • UIImage's drawInrect: smoothes image
  • Hiding preferences items in the settings bundle
  • Different image when button from storyboard tapped
  • iOS 7 - Long running background task
  • Configuring Cocoapods with an existing static library and iOS application
  • How can i implement the same functionality using apple map kit?

    I have tried to use the Geo Coder, i wrote this for example:

    @IBAction func SubmitGeoCode(sender: AnyObject) {
        let address = "1 Mart"
        let coder = CLGeocoder()
        coder.geocodeAddressString(address) { (placemarks, error) -> Void in
            for placemark in placemarks! {
                let lines = placemark.addressDictionary?["FormattedAddressLines"] as? [String]
                for addressline in lines! {

    However the results are very disappointing.

    Any Apple APIs available to implement such functionality, or should i head for google api ?

    Thank you

    3 Solutions Collect From Internet About “How to implement auto-complete for address using Apple Map Kit”

    Update – I’ve created a simple example project here using Swift 3 as the original answer was written in Swift 2.

    In iOS 9.3 a new class called MKLocalSearchCompleter was introduced, this allows the creation of an autocomplete solution, you simply pass in the queryFragment as below:

    var searchCompleter = MKLocalSearchCompleter()
    searchCompleter.delegate = self
    var searchResults = [MKLocalSearchCompletion]()
    searchCompleter.queryFragment = searchField.text!

    Then handle the results of the query using the MKLocalSearchCompleterDelegate:

    extension SearchViewController: MKLocalSearchCompleterDelegate {
        func completerDidUpdateResults(completer: MKLocalSearchCompleter) {
            searchResults = completer.results
        func completer(completer: MKLocalSearchCompleter, didFailWithError error: NSError) {
            // handle error

    And display the address results in an appropriate format:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let searchResult = searchResults[indexPath.row]
        let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: nil)
        cell.textLabel?.text = searchResult.title
        cell.detailTextLabel?.text = searchResult.subtitle
        return cell

    You can then use a MKLocalCompletion object to instantiate a MKLocalSearchRequest, thus gaining access to the MKPlacemark and all other useful data:

    let searchRequest = MKLocalSearchRequest(completion: completion!)
    let search = MKLocalSearch(request: searchRequest)
    search.startWithCompletionHandler { (response, error) in
        let coordinate = response?.mapItems[0].placemark.coordinate

    My answer is fully based on @George McDonnell’s. I hope it helps to guys who has troubles with implementing of the last one.

    import UIKit
    import MapKit
    class ViewController: UIViewController {
        @IBOutlet weak var searchBar: UISearchBar!
        @IBOutlet weak var tableVIew: UITableView!
        //create a completer
        lazy var searchCompleter: MKLocalSearchCompleter = {
            let sC = MKLocalSearchCompleter()
            sC.delegate = self
            return sC
        var searchSource: [String]?
    extension ViewController: UISearchBarDelegate {
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            //change searchCompleter depends on searchBar's text
            if !searchText.isEmpty {
                searchCompleter.queryFragment = searchText
    extension ViewController: UITableViewDelegate, UITableViewDataSource {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return searchSource?.count ?? 0
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            //I've created SearchCell beforehand; it might be your cell type
            let cell = self.tableVIew.dequeueReusableCell(withIdentifier: "SearchCell", for: indexPath) as! SearchCell
            cell.label.text = self.searchSource?[indexPath.row]
    //            + " " + searchResult.subtitle
            return cell
    extension ViewController: MKLocalSearchCompleterDelegate {
        func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
            //get result, transform it to our needs and fill our dataSource
            self.searchSource = { $0.title }
            DispatchQueue.main.async {
        func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
            //handle the error

    You should definitely head for Google APIs. I have struggled for a long time with Apple’s geocoding APIs and I can assure you that they are of very limited quality.

    If you want to see the clearest example of such low quality, check this question of mine.

    With Google’s APIs you can achieve much more accurate results. In addition, they have Autocomplete APIs. You can find out more about them here.

    I have tried them and managed to make them working quite nicely.