Как получить форматированный адрес NSString из AddressDictionary?
Попытка получить форматированный адрес из AddressDictionary, который я получил от CLGeocoder.
Используется следующий код без результата:
subtitle = [NSString stringWithString:[[addressDict objectForKey:@"FormattedAddressLines"]objectAtIndex:0]];
Также попытался:
subtitle = [[[ABAddressBook sharedAddressBook] formattedAddressFromDictionary:placemark.addressDictionary] string];
но этот код работает только на Mac OS X.
Компилятор спрашивает об ABAdressBook, но у меня есть оба импортированных файла заголовка.
#import <AddressBook/ABAddressBook.h>
#import <AddressBook/AddressBook.h>
Ответы
Ответ 1
В документации для свойства addressDictionary
указано:
Вы можете отформатировать содержимое этого словаря, чтобы получить полный адрес строка в отличие от создания адреса самостоятельно. Чтобы отформатировать словаря, используйте функцию ABCreateStringWithAddressDictionary как описанных в Справочнике функций адресной книги адреса.
Итак, добавьте и импортируйте фреймворк AddressBookUI
и попробуйте:
subtitle =
ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO);
Ответ 2
После некоторого копирования в 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);
}];
Я еще не мог найти документацию об этом, но он работает для всех адресов, которые я тестировал.
Ответ 3
Как указано Мартином Дэвисом, ABCreateStringWithAddressDictionary
устарел в iOS 9.
Вы можете использовать приведенные ниже функции, чтобы преобразовать addressDictionary
в новый CNMutablePostalAddress
, а затем использовать CNPostalAddressFormatter
для генерации локализованной строки до тех пор, пока вы импортируете фреймворк Contacts
.
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)
}
})
}
}
Выше - это быстрая версия.
Ответ 5
Я использую Swift 3/XCode 8
Ответ ZYiOS был приятным и коротким, но не компилировался для меня.
Задан вопрос о том, как получить из существующего словаря адресов в строковый адрес. Это то, что я сделал:
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 Помощник 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
}
Ответ 7
Просто создайте расширение для 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])
}
}
}
Пример:
let location = CLLocation()
location.addressDictionary { dictionary in
let city = dictionary?["City"] as? String
let street = dictionary?["Street"] as? String
}