Ich möchte die Adresse für den Benutzer automatisch vervollständigen, wie es in diesem Link von Google API vorgesehen ist:
https://developers.google.com/maps/documentation/javascript/places-autocomplete?hl=de
Wie kann ich die gleiche Funktionalität mit dem Apple Map Kit implementieren?
Ich habe versucht, den Geo Coder zu verwenden, ich schrieb dies zum Beispiel:
@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)
}
}
}
}
Die Ergebnisse sind jedoch sehr enttäuschend.
Vorhandene Apple-APIs, um solche Funktionen zu implementieren, oder sollte ich mich für Google API entscheiden?
Vielen Dank
Update - Ich habe ein einfaches Beispielprojekt hier erstellt, das Swift 3 verwendet, da die ursprüngliche Antwort in Swift 2 geschrieben wurde.
In iOS 9.3 wurde eine neue Klasse mit dem Namen MKLocalSearchCompleter
eingeführt, die die Erstellung einer Autocomplete-Lösung ermöglicht. Sie geben das queryFragment wie folgt weiter:
var searchCompleter = MKLocalSearchCompleter()
searchCompleter.delegate = self
var searchResults = [MKLocalSearchCompletion]()
searchCompleter.queryFragment = searchField.text!
Behandeln Sie dann die Ergebnisse der Abfrage mit der Variablen MKLocalSearchCompleterDelegate
:
extension SearchViewController: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(completer: MKLocalSearchCompleter) {
searchResults = completer.results
searchResultsTableView.reloadData()
}
func completer(completer: MKLocalSearchCompleter, didFailWithError error: NSError) {
// handle error
}
}
Und zeigen Sie die Adressergebnisse in einem geeigneten Format an:
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
}
Sie können dann ein MKLocalCompletion
-Objekt verwenden, um eine MKLocalSearchRequest
zu instanziieren, um Zugriff auf die MKPlacemark
und alle anderen nützlichen Daten zu erhalten:
let searchRequest = MKLocalSearchRequest(completion: completion!)
let search = MKLocalSearch(request: searchRequest)
search.startWithCompletionHandler { (response, error) in
let coordinate = response?.mapItems[0].placemark.coordinate
}
Meine Antwort basiert vollständig auf @ George McDonnell's. Ich hoffe, es hilft Jungs, die Probleme mit der Implementierung des letzten haben.
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)
}
}
Sie sollten sich auf jeden Fall für Google APIs entscheiden. Ich habe lange Zeit mit Apples Geokodierungs-APIs gekämpft, und ich kann Ihnen versichern, dass sie von sehr geringer Qualität sind.
Wenn Sie das klarste Beispiel für eine solche schlechte Qualität sehen möchten, aktivieren Sie die this -Frage von mir.
Mit den APIs von Google können Sie wesentlich genauere Ergebnisse erzielen. Darüber hinaus verfügen sie über Autocomplete-APIs. Sie können mehr über sie erfahren hier .
Ich habe sie ausprobiert und es geschafft, dass sie recht gut funktionieren.
PROBEPROJEKT FÜR DIESE AUSGABE KANN DOWNLOADEN von HIER
In diesem Beispielprojekt wird dieses Problem durch MKLocalSearchRequest und MapKit gelöst.
Es zeigt Autocomplete-Orte wie die Google Places-API und kann den Anmerkungspunkt auf Apples Karte platzieren (nicht auf Google-Karte, ich hoffe, dass nur Sie suchen.)
Es werden jedoch nicht so genaue Ergebnisse angezeigt, wie Sie mit der Google Places-API erhalten können. Das Problem ist, dass die Geokodierungsdatenbank offensichtlich nicht vollständig ist und Apple nicht das Unternehmen ist, das dieses Feld anführt - Google ist.
Fügen Sie einige Screenshots der Beispiel-App hinzu, damit Sie sehen können, ob dies für Ihre Anforderungen nützlich ist oder nicht.
Hoffe, das ist was Sie suchen!