Swift 4.1(还有3和4,只需保存1行)
我理解这个问题是在问“我该如何实现这个?”:
extension String {
init?(placemark: CLPlacemark?) {
}
}
两种方法
我首先尝试了转移AddressDictionary方法,与其他发帖者一样。但这意味着失去了CNPostalAddress类和格式化器的强大灵活性。因此,采用第二种方法。
extension String {
init?(depreciated placemark1: CLPlacemark?) {
guard
let myAddressDictionary = placemark1?.addressDictionary,
let myAddressLines = myAddressDictionary["FormattedAddressLines"] as? [String]
else { return nil }
self.init(myAddressLines.joined(separator: " "))
}
init?(betterMethod placemark2: CLPlacemark?) {
guard let postalAddress = CNMutablePostalAddress(placemark: placemark2) else { return nil }
self.init(CNPostalAddressFormatter().string(from: postalAddress))
}
}
等等,那个CLPlacemark
→ CNPostalAddress
的初始化器是什么?
extension CNMutablePostalAddress {
convenience init(placemark: CLPlacemark) {
self.init()
street = [placemark.subThoroughfare, placemark.thoroughfare]
.compactMap { $0 }
.joined(separator: " ")
city = placemark.locality ?? ""
state = placemark.administrativeArea ?? ""
postalCode = placemark.postalCode ?? ""
country = placemark.country ?? ""
isoCountryCode = placemark.isoCountryCode ?? ""
if #available(iOS 10.3, *) {
subLocality = placemark.subLocality ?? ""
subAdministrativeArea = placemark.subAdministrativeArea ?? ""
}
}
}
使用方法
func quickAndDirtyDemo() {
let location = CLLocation(latitude: 38.8977, longitude: -77.0365)
CLGeocoder().reverseGeocodeLocation(location) { (placemarks, _) in
if let address = String(depreciated: placemarks?.first) {
print("\nAddress Dictionary method:\n\(address)") }
if let address = String(betterMethod: placemarks?.first) {
print("\nEnumerated init method:\n\(address)") }
}
}
读到这里的人可以获得一件免费的T恤。(并不是真的)
*此代码可在Swift 3和4中使用,除了在Swift 4.1中已经弃用/重命名为compactMap
的flatMap
用于删除空值(文档在这里,或者查看SE-187的原因)。
addressDictionary
在iOS 11中已经被废弃。技术巨头正在不断向前推进... - AmitaiBCLPlacemark
得到了var postalAddress: CNPostalAddress? { get }
属性,整个线程都被Sherlock了! - AmitaiB