ios 如何从 AddressDictionary 获取格式化地址 NSString?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7848291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:59:09  来源:igfitidea点击:

How to get formatted address NSString from AddressDictionary?

iosaddressbookclgeocoder

提问by Shmidt

Trying to get formatted address from AddressDictionary, that I got from CLGeocoder. Used following code with no result:

试图从 AddressDictionary 获取格式化地址,这是我从 CLGeocoder 获得的。使用以下代码没有结果:

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.

但此代码似乎仅适用于 Mac OS X。

Compiler asks about ABAdressBook, but I have both header files imported.

编译器询问 ABAdressBook,但我已导入两个头文件。

#import <AddressBook/ABAddressBook.h>
#import <AddressBook/AddressBook.h>

回答by

The documentation for the addressDictionaryproperty says:

addressDictionary物业的文件说:

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.

您可以格式化此字典的内容以获得完整的地址字符串,而不是自己构建地址。若要格式化字典,请使用通讯簿 UI 函数参考中所述的 ABCreateStringWithAddressDictionary 函数。

So add and import the AddressBookUIframework and try:

所以添加并导入AddressBookUI框架并尝试:

subtitle = 
    ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO);

回答by Klaas

After doing some digging under iOS 6.1 I found out that the CLPlacemark address dictionary contains a pre-formatted address:

在 iOS 6.1 下做了一些挖掘后,我发现 CLPlacemark 地址字典包含一个预先格式化的地址:

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.

我还找不到关于此的文档,但它适用于我测试过的所有地址。

回答by tebs1200

As highlighted by Martyn Davis, ABCreateStringWithAddressDictionaryis deprecated in iOS 9.

正如 Martyn Davis 所强调的,ABCreateStringWithAddressDictionary在 iOS 9 中已被弃用。

You can use the functions below to convert the addressDictionaryto the newer CNMutablePostalAddress, then use the CNPostalAddressFormatterto generate a localised string as long as you import the Contactsframework.

您可以使用下面的函数将 转换addressDictionary为较新的CNMutablePostalAddress,然后CNPostalAddressFormatter只要您导入Contacts框架,就可以使用生成本地化的字符串。

Swift 3.x

斯威夫特 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

斯威夫特 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)
}

回答by ZYiOS

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.

以上是swift版本。

回答by Nick Graham

I am using Swift 3 / XCode 8

我正在使用 Swift 3 / XCode 8

ZYiOS's answerwas nice and short but did not compile for me.

ZYiOS 的回答很好而且很简短,但没有为我编译。

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
}

回答by Sourabh Sharma

Swift 3 / Xcode 8Helper Mehtod to get address from CLPlaceMark

Swift 3 / Xcode 8Helper Mehtod 从 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
  }

回答by Bart?omiej Semańczyk

Simply create extension for CLLocation:

只需创建扩展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
}

回答by mini coder

Swift 5 version

斯威夫特 5 版本

CLGeocoder().reverseGeocodeLocation(newLocation!, preferredLocale: nil) { (clPlacemark: [CLPlacemark]?, error: Error?) in
            guard let place = clPlacemark?.first else {
                print("No placemark from Apple: \(String(describing: error))")
                return
            }

            if let addrList = place.addressDictionary?["FormattedAddressLines"] as? [String] {
                let addressString = addrList.joined(separator: ", ")
                print(addressString)

            }
        }