##郵便番号から住所を取得する
CLGeocoderには標準で
func geocodeAddressString(_ addressString: String, completionHandler: @escaping CLGeocodeCompletionHandler)
こちらの郵便番号から住所を取得するメソッドがあるのですが、これで取得するとCLPlacemarkのsubLocality
が取得できませんでした。
そのため、一度このメソッドを使って取得した住所の緯度経度を使ってCLLocationを作り
func reverseGeocodeLocation(_ location: CLLocation, completionHandler: @escaping CLGeocodeCompletionHandler)
こちらのCLLocationから住所を取得するメソッドを使うことでsubLocality
が取得することができます。
扱いやすいようにCLGeocoderにextensionで上記の方法で郵便番号から住所を取得するメソッドを追加すると良いかと思います。
extension CLGeocoder {
struct Address {
var administrativeArea: String? // 都道府県 例) 東京都
var locality: String? // 市区町村 例) 墨田区
var subLocality: String? // 地名 例) 押上
}
func convertAddress(from postalCode: String, completion: @escaping (Address?, Error?) -> Void) {
CLGeocoder().geocodeAddressString(postalCode) { (placemarks, error) in
if let error = error {
completion(nil, error)
return
}
if let placemark = placemarks?.first {
let location = CLLocation(
latitude: (placemark.location?.coordinate.latitude)!,
longitude: (placemark.location?.coordinate.longitude)!
)
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
guard let placemark = placemarks?.first, error == nil else {
completion(nil, error)
return
}
var address: Address = Address()
address.administrativeArea = placemark.administrativeArea
address.locality = placemark.locality
address.subLocality = placemark.subLocality
completion(address, nil)
}
}
}
}
}
// 郵便番号はハイフンなしでも取得可能です
CLGeocoder().convertAddress(from: "131-0045") { (address, error) in
if let error = error {
print(error)
return
}
print(address?.administrativeArea) // → 東京都
print(address?.locality) // → 墨田区
print(address?.subLocality) // → 押上
}