I'm trying to build a autocomplete textfield which needs to display the city/town name only.
So what I want to do is that when someone enters
Am
it will show
Amsterdam
Amstelveen
So it will only display the actual city names and nothing beyond that. It doesn't need to take places neighbourhoods etc into consideration.
I've applied a filter already but this doesn't fix it.
lazy var searchCompleter: MKLocalSearchCompleter = {
let sC = MKLocalSearchCompleter()
sC.delegate = self
sC.filterType = .locationsOnly
return sC
}()
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
self.searchSource = completer.results.map { $0.title }
DispatchQueue.main.async {
for result in self.searchSource! {
print(result)
}
}
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
print(error.localizedDescription)
}
Does anyone know if it's possible to achieve what I want?
I've been looking for a way to do this in one of my apps, but MKLocalSearchCompletion does not seem to be the ideal tool for this. Using Google's Map API or just a local database of city names might be simpler.
Another option within the iOS native frameworks would be to make use of the related MKLocalSearchRequest and extracting the 'locality' field, which most closely corresponds to city/town. More information about going down this route is provided in this post:
How to extract country and city from MKLocalSearchCompletion?
Having said that, I did make some headway using just MKLocalSearchCompletion, by parsing the title property in returned results to check for a 'comma' character. The presence of a comma indicates that the entire string up to the first comma is a town, city, or state. The simple example below takes the textfield input and returns only the filtered results in a tableview.
I have to note that it seems to work well for cities in the United States because the MKLocalSearchCompletion database seems to be much more complete for that region. Some international cities do not show, as results do not follow the same 'comma' format which this method utilizes.
import UIKit
import MapKit
class ViewController: UIViewController, MKLocalSearchCompleterDelegate, UITableViewDelegate, UITableViewDataSource {
var completer = MKLocalSearchCompleter()
var completionResults: [MKLocalSearchCompletion] = []
var cityResults: [String] = [] {
didSet {
citySearchTable.reloadData()
}
}
@IBOutlet weak var citySearchTable: UITableView!
@IBAction func cityTextChanged(_ sender: UITextField) {
completer.queryFragment = sender.text!
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let coordUSA = CLLocationCoordinate2DMake(39.999733,-98.678503);
completer.region = MKCoordinateRegion(center: coordUSA, latitudinalMeters: 1, longitudinalMeters: 1)
completer.delegate = self
citySearchTable.delegate = self
citySearchTable.dataSource = self
}
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
completionResults = completer.results
completionResults = completionResults.filter({ (result) -> Bool in
return result.title != ""
})
if completionResults.count > 0 {
var newResults: [String] = []
for result in completionResults {
if result.title.contains(",") {
let splitByComma = result.title.components(separatedBy: ",")
if splitByComma.count > 0 {
if !newResults.contains(splitByComma[0]) {
newResults.append(splitByComma[0])
}
}
}
}
if newResults.count > 0 {
cityResults = newResults
}
}
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
//
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cityResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = citySearchTable.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = cityResults[indexPath.row]
cell.textLabel?.adjustsFontSizeToFitWidth = true
return cell
}
}
I know this post is a couple of years old, however it did come up in my recent research, and is relevant to my current work, so I thought I would post what I came up with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With