可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Trying to get formatted address from AddressDictionary, that I got from CLGeocoder.
Used following code with no result:
subtitle = [NSString stringWithString:[[addressDict objectForKey:@"FormattedAddressLines"]objectAtIndex:0]];
Also tried:
subtitle = [[[ABAddressBook sharedAddressBook] formattedAddressFromDictionary:placemark.addressDictionary] string];
but this code seems working on Mac OS X only.
Compiler asks about ABAdressBook, but I have both header files imported.
#import <AddressBook/ABAddressBook.h>
#import <AddressBook/AddressBook.h>
回答1:
The documentation for the addressDictionary
property says:
You can format the contents of this dictionary to get a full address
string as opposed to building the address yourself. To format the
dictionary, use the ABCreateStringWithAddressDictionary function as
described in Address Book UI Functions Reference.
So add and import the AddressBookUI
framework and try:
subtitle =
ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO);
回答2:
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.
回答3:
As highlighted by Martyn Davis, ABCreateStringWithAddressDictionary
is deprecated in iOS 9.
You can use the functions below to convert the addressDictionary
to the newer CNMutablePostalAddress
, then use the CNPostalAddressFormatter
to generate a localised string as long as you import the Contacts
framework.
Swift 3.x
// Convert to the newer CNPostalAddress
func postalAddressFromAddressDictionary(_ addressdictionary: Dictionary<NSObject,AnyObject>) -> CNMutablePostalAddress {
let address = CNMutablePostalAddress()
address.street = addressdictionary["Street" as NSObject] as? String ?? ""
address.state = addressdictionary["State" as NSObject] as? String ?? ""
address.city = addressdictionary["City" as NSObject] as? String ?? ""
address.country = addressdictionary["Country" as NSObject] as? String ?? ""
address.postalCode = addressdictionary["ZIP" as NSObject] as? String ?? ""
return address
}
// Create a localized address string from an Address Dictionary
func localizedStringForAddressDictionary(addressDictionary: Dictionary<NSObject,AnyObject>) -> String {
return CNPostalAddressFormatter.string(from: postalAddressFromAddressDictionary(addressDictionary), style: .mailingAddress)
}
Swift 2.x
import Contacts
// Convert to the newer CNPostalAddress
func postalAddressFromAddressDictionary(addressdictionary: Dictionary<NSObject,AnyObject>) -> CNMutablePostalAddress {
let address = CNMutablePostalAddress()
address.street = addressdictionary["Street"] as? String ?? ""
address.state = addressdictionary["State"] as? String ?? ""
address.city = addressdictionary["City"] as? String ?? ""
address.country = addressdictionary["Country"] as? String ?? ""
address.postalCode = addressdictionary["ZIP"] as? String ?? ""
return address
}
// Create a localized address string from an Address Dictionary
func localizedStringForAddressDictionary(addressDictionary: Dictionary<NSObject,AnyObject>) -> String {
return CNPostalAddressFormatter.stringFromPostalAddress(postalAddressFromAddressDictionary(addressDictionary), style: .MailingAddress)
}
回答4:
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.
回答5:
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
}
回答6:
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
}
回答7:
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
}