В одном из моих приложений мне нужно добавить возможность найти город по его названию. Я использую CLGeocoder
для достижения этого, и я хочу, чтобы у него было поведение, идентичное погодному приложению iOS.
Ниже приведен код, который у меня есть:
CLGeocoder().geocodeAddressString(searchBar.text!, completionHandler:{ (placemarks, error) -> Void in
guard let nonNilMarks = placemarks else {return}
for placemark in nonNilMarks {
print("locality: \(placemark.locality)")
print("name: \(placemark.name)")
print("country: \(placemark.country)")
print("formatted address: \(placemark.addressDictionary)")
}
})
В большинстве случаев он работает очень хорошо. Тем не менее, я недавно заметил некоторые случаи, когда он терпит неудачу. Ниже приведено несколько примеров:
Поиск "Милана" - РАБОТЫ
locality: Optional("Milan")
name: Optional("Milan")
country: Optional("Italy")
formatted address: Optional([SubAdministrativeArea: Milan, State: Lombardy, CountryCode: IT, Country: Italy, Name: Milan, FormattedAddressLines: (
Milan,
Italy
), City: Milan])
Это правильный вывод
Поиск "Италия, TX" - РАБОТЫ
В Техасе есть город, называемый Италией. Если я нахожу "Италия, TX", выход:
locality: Optional("Italy")
name: Optional("Italy")
country: Optional("United States")
formatted address: Optional([SubAdministrativeArea: Ellis, State: TX, CountryCode: US, Country: United States, Name: Italy, FormattedAddressLines: (
"Italy, TX",
"United States"
), City: Italy])
Поиск "Италия" - FAILS
Когда я печатаю только "Италию", я получаю только местную отметку для страны:
locality: nil
name: Optional("Italy")
country: Optional("Italy")
formatted address: Optional([CountryCode: IT, Name: Italy, FormattedAddressLines: (
Italy
), Country: Italy])
Поиск "Сингапур, Сингапур" - РАБОТЫ
Это похоже на случай с 'Italy, TX':
locality: Optional("Singapore")
name: Optional("Singapore")
country: Optional("Singapore")
formatted address: Optional([City: Singapore, CountryCode: SG, Name: Singapore, State: Singapore, FormattedAddressLines: (
Singapore,
Singapore
), Country: Singapore])
Поиск "Сингапур" - FAILS
Опять же, похоже на случай с "Италией". Он находит только страну:
locality: nil
name: Optional("Singapore")
country: Optional("Singapore")
formatted address: Optional([CountryCode: SG, Name: Singapore, FormattedAddressLines: (
Singapore
), Country: Singapore])
Предварительное предположение
На этом этапе я, хотя, возможно, geocodeAddressString:
останавливает поиск, если он находит страну с именем, равным параметру поиска, поэтому я попытался изменить свой код на:
let addrDict = [kABPersonAddressCityKey as NSString: searchBar.text!]
CLGeocoder().geocodeAddressDictionary(addrDict, completionHandler:{ (placemarks, error) -> Void in
print(placemarks)
})
Я думал, что, ограничив поисковый термин на название города, я получу правильные результаты. К сожалению, я получаю то же самое поведение!
И THEN Я понял, что у меня проблемы с не только случаем, когда название города равно имени страны.
Поиск "Токио" - FAIC FAIL
locality: nil
name: Optional("Tokyo")
country: Optional("Japan")
formatted address: Optional([CountryCode: JP, Name: Tokyo, State: Tokyo, FormattedAddressLines: (
Tokyo,
Japan
), Country: Japan])
Заключение
Не только CLGeocoder
опускать результаты (например, в случае с "Италией" ), но также может сказать мне, что в месте нет locality
, когда на самом деле это происходит (я считаю, что в прошлый раз я проверил карту Токио все еще был городом!).
Кто-нибудь знает, как я могу решить любую из этих проблем?
Погода приложение делает это как-то - поиск "Сингапур" или "Италия" дает правильные результаты. Буду благодарен за любую помощь!
P.S. Хотя я использую Swift, я добавляю Objective-C в качестве тега, поскольку я думаю, что этот вопрос не является специфичным для Swift.