Поиск географических названий (города / населенного пункта) с помощью MKLocalSearchCompleter

Я пытаюсь создать текстовое поле автозаполнения, которое должно отображать только название города / населенного пункта.

Так что я хочу сделать, это когда кто-то входит

Am это покажет

Амстердам
Амстелвеен

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

Я уже применил фильтр, но это не помогает.

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)
    }

Кто-нибудь знает, возможно ли добиться того, чего я хочу?

0 ответов

Я искал способ сделать это в одном из моих приложений, но MKLocalSearchCompletion не кажется идеальным инструментом для этого. Может быть проще использовать Google Map API или просто локальную базу данных названий городов.

Другой вариант в рамках собственных фреймворков iOS - использовать связанный MKLocalSearchRequest и извлечь поле "местонахождение", которое наиболее точно соответствует городу / городу. Больше информации о том, как пойти по этому маршруту, можно найти в этом посте:

Как извлечь страну и город из MKLocalSearchCompletion?

Сказав это, я добился некоторого прогресса, используя только MKLocalSearchCompletion, проанализировав свойство title в возвращаемых результатах, чтобы проверить наличие символа "запятая". Наличие запятой означает, что вся строка до первой запятой - это город, город или штат. В приведенном ниже простом примере вводится текстовое поле, а в табличном представлении возвращаются только отфильтрованные результаты.

Я должен отметить, что, похоже, это хорошо работает для городов в Соединенных Штатах, потому что база данных MKLocalSearchCompletion кажется гораздо более полной для этого региона. Некоторые международные города не отображаются, так как результаты не имеют того же формата "запятая", который используется в этом методе.

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
    }

}

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

Другие вопросы по тегам