How to get formatted address NSString from Address

2019-01-25 05:24发布

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>

7条回答
手持菜刀,她持情操
2楼-- · 2019-01-25 05:48

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
  }
查看更多
冷血范
3楼-- · 2019-01-25 05:52
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.

查看更多
女痞
4楼-- · 2019-01-25 05:53

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.

查看更多
爷、活的狠高调
5楼-- · 2019-01-25 05:57

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)
}
查看更多
干净又极端
6楼-- · 2019-01-25 06:00

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);
查看更多
做个烂人
7楼-- · 2019-01-25 06:07

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
}
查看更多
登录 后发表回答