Trying to get formatted address from AddressDictionary, that I got from CLGeocoder. Used following code with no result:
subtitle = [NSString stringWithString
After doing some digging under iOS 6.1 I found out that the CLPlacemark address dictionary contains a pre-formatted address:
CLLocation *location = [[CLLocation alloc]initWithLatitude:37.3175 longitude:-122.041944];
[[[CLGeocoder alloc]init] reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = placemarks[0];
NSArray *lines = placemark.addressDictionary[ @"FormattedAddressLines"];
NSString *addressString = [lines componentsJoinedByString:@"\n"];
NSLog(@"Address: %@", addressString);
}];
I couldn't yet find documentation about this, but it works for all the addresses that I tested.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// get the address
if let location = locations.last {
CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (result: [CLPlacemark]?, err: NSError?) -> Void in
if let placemark = result?.last
, addrList = placemark.addressDictionary?["FormattedAddressLines"] as? [String]
{
let address = addrList.joinWithSeparator(", ")
print(address)
}
})
}
}
Above is the swift version.
I am using Swift 3 / XCode 8
ZYiOS's answer was nice and short but did not compile for me.
The question asks how to get from an existing Address Dictionary to a string address. This is what I did:
import CoreLocation
func getAddressString(placemark: CLPlacemark) -> String? {
var originAddress : String?
if let addrList = placemark.addressDictionary?["FormattedAddressLines"] as? [String]
{
originAddress = addrList.joined(separator: ", ")
}
return originAddress
}
Simply create extension for CLLocation
:
typealias AddressDictionaryHandler = ([String: Any]?) -> Void
extension CLLocation {
func addressDictionary(completion: @escaping AddressDictionaryHandler) {
CLGeocoder().reverseGeocodeLocation(self) { placemarks, _ in
completion(placemarks?.first?.addressDictionary as? [String: AnyObject])
}
}
}
Example:
let location = CLLocation()
location.addressDictionary { dictionary in
let city = dictionary?["City"] as? String
let street = dictionary?["Street"] as? String
}
Swift 3 / Xcode 8 Helper Mehtod to get address from CLPlaceMark
class func formattedAddress(fromPlacemark placemark: CLPlacemark) -> String{
var address = ""
if let name = placemark.addressDictionary?["Name"] as? String {
address = constructAddressString(address, newString: name)
}
if let city = placemark.addressDictionary?["City"] as? String {
address = constructAddressString(address, newString: city)
}
if let state = placemark.addressDictionary?["State"] as? String {
address = constructAddressString(address, newString: state)
}
if let country = placemark.country{
address = constructAddressString(address, newString: country)
}
return address
}
Now this is as simple as
func updateUserAddress(coordinates: CLLocationCoordinate2D) {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: coordinates.latitude, longitude: coordinates.longitude)
geoCoder.reverseGeocodeLocation(location) {[weak self] (placemarks, error) in
if error == nil, let placemark = placemarks?.first, let address = placemark.postalAddress {
self?.userLocationLabel.text = CNPostalAddressFormatter.string(from: address, style: .mailingAddress)
}
}
}