我正在尝试编写一个简单的方法,该方法已馈入CLLocationDegrees并返回CLPlacemark。查看Apple的文档,这似乎很简单。
CLLocationDegrees
CLPlacemark
以下是我丢到操场上的东西:
import CoreLocation // this is necessary for async code in a playground import PlaygroundSupport // this is necessary for async code in a playground PlaygroundPage.current.needsIndefiniteExecution = true func geocode(latitude: CLLocationDegrees, longitude: CLLocationDegrees) -> CLPlacemark? { let location = CLLocation(latitude: latitude, longitude: longitude) let geocoder = CLGeocoder() var placemark: CLPlacemark? geocoder.reverseGeocodeLocation(location) { (placemarks, error) in if error != nil { print("something went horribly wrong") } if let placemarks = placemarks { placemark = placemarks.first } } return placemark } let myPlacemark = geocode(latitude: 37.3318, longitude: 122.0312)
就目前而言,我的方法返回nil。我不确定我的错误在哪里,但是我可以放心,这对我来说是愚蠢的。感谢您的阅读。
import UIKit import CoreLocation import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true
func geocode(latitude: Double, longitude: Double, completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void) { CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude)) { placemark, error in guard let placemark = placemark, error == nil else { completion(nil, error) return } completion(placemark, nil) } }
或者简单地:
func geocode(latitude: Double, longitude: Double, completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void) { CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude), completionHandler: completion) }
或扩展CLLocation:
extension CLLocation { func geocode(completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void) { CLGeocoder().reverseGeocodeLocation(self, completionHandler: completion) } }
要将地标格式化为邮寄地址,可以使用“联系人”框架CNPostalAddressFormatter:
CNPostalAddressFormatter
import Contacts extension Formatter { static let mailingAddress: CNPostalAddressFormatter = { let formatter = CNPostalAddressFormatter() formatter.style = .mailingAddress return formatter }() } extension CLPlacemark { var mailingAddress: String? { return postalAddress?.mailingAddress } } extension CNPostalAddress { var mailingAddress: String { return Formatter.mailingAddress.string(from: self) } }
地标 包含CLPlacemark对象的数组。对于大多数地理编码请求,此数组应仅包含一个条目。但是,在无法将指定地址解析到单个位置的情况下,前向地理编码请求可能会返回多个地标对象。如果请求被取消或获取地标信息时出错,则此参数为nil。
地标
包含CLPlacemark对象的数组。对于大多数地理编码请求,此数组应仅包含一个条目。但是,在无法将指定地址解析到单个位置的情况下,前向地理编码请求可能会返回多个地标对象。如果请求被取消或获取地标信息时出错,则此参数为nil。
有关CLPlacemark属性的更多信息,可以检查此CLPlacemark
用法:
let location = CLLocation(latitude: -22.963451, longitude: -43.198242) location.geocode { placemark, error in if let error = error as? CLError { print("CLError:", error) return } else if let placemark = placemark?.first { // you should always update your UI in the main thread DispatchQueue.main.async { // update UI here print("name:", placemark.name ?? "unknown") print("address1:", placemark.thoroughfare ?? "unknown") print("address2:", placemark.subThoroughfare ?? "unknown") print("neighborhood:", placemark.subLocality ?? "unknown") print("city:", placemark.locality ?? "unknown") print("state:", placemark.administrativeArea ?? "unknown") print("subAdministrativeArea:", placemark.subAdministrativeArea ?? "unknown") print("zip code:", placemark.postalCode ?? "unknown") print("country:", placemark.country ?? "unknown", terminator: "\n\n") print("isoCountryCode:", placemark.isoCountryCode ?? "unknown") print("region identifier:", placemark.region?.identifier ?? "unknown") print("timezone:", placemark.timeZone ?? "unknown", terminator:"\n\n") // Mailind Address print(placemark.mailingAddress ?? "unknown") } } }
这将打印
name: Morro da Saudade address1: Rua Casuarina address2: 597 neighborhood: Lagoa city: Rio de Janeiro state: RJ subAdministrativeArea: unknown zip code: 22011-040 country: Brazil isoCountryCode: BR region identifier: <-22.96345100,-43.19824200> radius 141.83 timezone: America/Sao_Paulo (current)
Rua Casuarina,597 拉哥亚 里约热内卢 22011-040 巴西
Rua Casuarina,597
拉哥亚
里约热内卢
22011-040
巴西