Как реализовать автозаполнение для адреса с помощью Apple Map Kit

Я хочу автоматически заполнить адрес для пользователя так же, как google api предоставляет по этой ссылке:

https://developers.google.com/maps/documentation/javascript/places-autocomplete?hl=en

Как я могу реализовать ту же функциональность с помощью apple map kit?

Я попытался использовать геокодер, я написал это, например:

@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! {
                print(addressline)
            }
        }
    }
}

однако результаты очень разочаровывают.

Любые API Apple доступно для реализации такой функциональности, или я должен отправиться в Google api ?

спасибо

4 ответов


Update-я создал простой пример проекта здесь использование Swift 3 в качестве исходного ответа было написано в Swift 2.

в iOS 9.3 новый класс называется MKLocalSearchCompleter был введен, это позволяет создавать решение автозаполнения, вы просто передаете в queryFragment, как показано ниже:

var searchCompleter = MKLocalSearchCompleter()
searchCompleter.delegate = self
var searchResults = [MKLocalSearchCompletion]()

searchCompleter.queryFragment = searchField.text!

затем обработайте результаты запроса с помощью MKLocalSearchCompleterDelegate:

extension SearchViewController: MKLocalSearchCompleterDelegate {

    func completerDidUpdateResults(completer: MKLocalSearchCompleter) {
        searchResults = completer.results
        searchResultsTableView.reloadData()
    } 

    func completer(completer: MKLocalSearchCompleter, didFailWithError error: NSError) {
        // handle error
    }
}

и отображать результаты в соответствующей формат:

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
}

затем вы можете использовать MKLocalCompletion объект для создания экземпляра a MKLocalSearchRequest, таким образом получая доступ к MKPlacemark и все другие полезные данные:

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

мой ответ полностью основан на @Джордж Макдоннелл по. Я надеюсь, что это помогает ребятам, кто имеет проблемы с реализацией последнего.

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 { .title }
        DispatchQueue.main.async {
            self.tableVIew.reloadData()
        }
    }

    func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
        //handle the error
        print(error.localizedDescription)
    }
}

вы определенно должны отправиться в Google APIs. Я долгое время боролся с API геокодирования Apple, и я могу заверить вас, что они имеют очень ограниченное качество.

Если вы хотите увидеть самый яркий пример такого низкого качества, проверьте этой вопрос мой.

с помощью API Google вы можете достичь гораздо более точных результатов. Кроме того, они имеют API автозаполнения. Вы можете узнать больше о них здесь.

I попробовали их и сумели заставить их работать довольно хорошо.


ПРИМЕР ПРОЕКТА ДЛЯ ЭТОЙ ПРОБЛЕМЫ МОЖНО ЗАГРУЗИТЬ ИЗ здесь

в этом примере проекта эта проблема достигается с помощью MKLocalSearchRequest и MapKit.

он показывает автозаполнение места так же, как Google places API и может разместить точку аннотации на карте Apple (не на карте Google, я надеюсь, что это только вы ищете.)

однако он не показывает точный результат, как вы можно получить из Google Places API. Поскольку проблема заключается в том, что база данных геокодирования явно не завершена, и Apple не является компанией, которая ведет эту область - Google.

прилагаю некоторые скриншоты образец приложение, так что вы можете увидеть, если это полезно для вашего требования или нет.

Apple's autocomplete view.

Plotting the annotation point on Apple's map.

надеюсь, это то, что вы ищете!