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

后端 未结 3 1162
孤独总比滥情好
孤独总比滥情好 2020-11-29 03:06

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

https://developers.google.com/maps/documentation/javascript/places

相关标签:
3条回答
  • 2020-11-29 03:26

    SAMPLE PROJECT FOR THIS ISSUE CAN BE DOWNLOAD FROM HERE

    In this sample project this issue is achieved through MKLocalSearchRequest and MapKit.

    It is showing autocomplete places just like google places API and can place the Annotation point on Apple's map (not on Google map, I hope that is only you are looking for.)

    However it does not show as accurate result as you can get from Google Places API. As the problem is that Geocoding database is not obviously complete and Apple is not the company who leads this field - Google is.

    Attaching some screenshots of the sample app, so you can see if it is useful for your requirement or not.

    Hope this is what you are looking for!

    0 讨论(0)
  • 2020-11-29 03:37

    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 = completer.results.map { $0.title }
            DispatchQueue.main.async {
                self.tableVIew.reloadData()
            }
        }
    
        func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
            //handle the error
            print(error.localizedDescription)
        }
    }
    
    0 讨论(0)
  • 2020-11-29 03:50

    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
            searchResultsTableView.reloadData()
        } 
    
        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 MKLocalSearch.Request, thus gaining access to the MKPlacemark and all other useful data:

    let searchRequest = MKLocalSearch.Request(completion: completion!)
    let search = MKLocalSearch(request: searchRequest)
    search.startWithCompletionHandler { (response, error) in
        if error == nil {
            let coordinate = response?.mapItems[0].placemark.coordinate
        }
    }
    
    0 讨论(0)
提交回复
热议问题