Поиск адреса с помощью SWIFT

#ios #swift #location

#iOS #быстрый #Расположение #swift

Вопрос:

В моем приложении мне нужно, чтобы пользователь ввел свой домашний адрес, но я никак не могу добиться, чтобы отображаемые адреса находились только в регионе пользователей и были полными адресами, например 225e 57th st, NY, New York .

Я хочу предоставить пользователю все перечисленные параметры в tableview и фильтровать их по мере ввода пользователем своего адреса.

Комментарии:

1. Как говорится в принятом ответе, эта проблема связана с завершением адреса и проверкой адреса. Просто для информации на будущее, если вы будете использовать эти фразы для поиска, вы найдете хорошую информацию.

Ответ №1:

Вы можете определить средство завершения локального поиска:

 let completer = MKLocalSearchCompleter()
  

А затем укажите фрагмент запроса:

 completer.delegate = self
completer.region = MKCoordinateRegion(center: currentCoordinate, latitudinalMeters: 10_000, longitudinalMeters: 10_000)
completer.queryFragment = "300 S Orange"
  

И реализовать MKLocalSearchCompleterDelegate протокол

 extension ViewController: MKLocalSearchCompleterDelegate {

    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
        let addresses = completer.results.map { result in
            result.title   ", "   result.subtitle
        }

        // use addresses, e.g. update model and call `tableView.reloadData()
    }

}
  

И это дает:

["300 S Orange Grove Blvd, Пасадена, Калифорния, США",
"300 S Orange Ave, Монтерей-Парк, Калифорния, США",
"300 S Orange St, Глендейл, Калифорния, США",
"300 S Orange Dr, Лос-Анджелес, Калифорния, США",
"300 S Orange Ave, Азуза, Калифорния, США",
"300 S Orange Grove Ave, Лос-Анджелес, Калифорния, США",
"300 S Orange Ave, Бреа, Калифорния, США",
"300 S Orange Ave, Фуллертон, Калифорния, США",
"300S Orange St, Ориндж, Калифорния, США",
"300 S Orange Ave, Риальто, Калифорния, США",
"300 S Orange Ave, Фоллбрук, Калифорния, США",
"300 S Orange St, Эскондидо, Калифорния, США",
"300 S Orange Ave,Эль-Кахон, Калифорния, США",
"300 S Orange Cir, Тулар, Калифорния, США",
"300 S Orange Ave, Эксетер, Калифорния, США"]

Или же вы можете выполнить локальный поиск:

 let request = MKLocalSearch.Request()
request.region = MKCoordinateRegion(center: currentCoordinate, latitudinalMeters: 10_000, longitudinalMeters: 10_000)
request.naturalLanguageQuery = "300 S Pumpkin"

let formatter = CNPostalAddressFormatter()
formatter.style = .mailingAddress

let search = MKLocalSearch(request: request)
search.start { response, error in
    let addresses = response?.mapItems.compactMap { item -> String? in
        return item.placemark.postalAddress.flatMap {
            formatter.string(from: $0).replacingOccurrences(of: "n", with: ", ")
        }
    }
    print(addresses)
}
  

Теперь я использую средство форматирования Contacts framework (которое также предоставляет postalAddress свойство для метки), но вы можете форматировать их любым удобным для вас способом. Но, предполагая, что он находит совпадения, это показывает что-то вроде:

["300 S Pumpkin Blvd, Лос-Анджелес, КАЛИФОРНИЯ 92108, США",
"300 S Pumpkin Pkwy, Лос-Анджелес, Калифорния 92103, США",
"300 S Pumpkin Dr, Сан-Габриэль, КАЛИФОРНИЯ 91776, США"])

Теперь, хотите ли вы FormattedAddressLines , или извлекать отдельные компоненты из addressDictionary , зависит от вас, но, надеюсь, это иллюстрирует идею.

Комментарии:

1. Большое вам спасибо, он работает так, как я хотел, но когда я использую MKLocalSearchRequest, наибольшее количество адресов, которые я получаю, равно 10, есть способ отменить ограничение?

2. Нет, я так не считаю. Очевидно, MKLocalSearchCompleter что может возвращать более 10 (и если вводимый адрес неполный, я действительно думаю, что он лучше подходит для обработки частичных записей).