ios - 如何本地化国际地址,尤其是大道和次大道
问题描述
我正在开发一个大量使用不同国家地址的应用程序。我们有很多方法可以输入它们,从导入地址到在地图上放置图钉,再到反向地理编码我们当前的位置。
我目前的项目是正确格式化国际地址:
在美国:
18 Street Name
在挪威:
Street Name 18
我已经想出了很多方法来实例化CNMutablePostalAddress
以CLPlacemark
获得一些很好的结果,我遇到的问题就是这个。
我只想将街道名称和号码作为单行字符串返回:所以:
street1: placemarker.thoroughfare, (street name)
street2: placemarker.subThoroughfare (street number),
但是 CNPostalAddress 只有一个street
属性,因此要使用它,您需要执行以下操作:
cNPostalAddress.street = placemarker.subThoroughfare + " " + placemarker.thoroughfare
这不适用于像挪威这样受人尊敬的国家。
您可以破解它并使用格式化地址中的第一行:
CNPostalAddressFormatter.string(from: placemarker.mailingAddress , style: .mailingAddress)
但这太老套了,我相信它会与像日本这样以不同方式订购邮寄地址的国家/地区决裂。
目前,我什至找不到任何资源可以告诉我哪些国家反转了subThoroughfare
,thoroughfare
因为如果我有这样的列表,我可以手动反转它。
这是我迄今为止管理的一些示例代码:
static func mulitLineAddress(from placemarker: CLPlacemark, detail: AddressDetail) -> String {
let address = MailingAddress(
street1: placemarker.thoroughfare,
street2: placemarker.subThoroughfare,
city: placemarker.locality,
state: placemarker.administrativeArea,
postalCode: placemarker.postalCode,
countryCode: placemarker.country)
return self.mulitLineAddress(from: address, detail: detail)
}
static func mulitLineAddress(from mailingAddress: MailingAddress, detail: AddressDetail) -> String {
let address = CNMutablePostalAddress()
let street1 = mailingAddress.street1 ?? ""
let street2 = mailingAddress.street2 ?? ""
let streetSpacing = street1.isEmpty && street2.isEmpty ? "" : " "
let streetFull = street1 + streetSpacing + street2
switch detail {
case .street1:
address.street = street1
case .street2:
address.street = street2
case .streetFull:
address.street = streetFull
case .full:
address.country = mailingAddress.countryCode ?? ""
fallthrough
case .withoutCountry:
address.street = streetFull
address.city = mailingAddress.city ?? ""
address.state = mailingAddress.state ?? ""
address.postalCode = mailingAddress.postalCode ?? ""
}
return CNPostalAddressFormatter.string(from: address, style: .mailingAddress)
}
有任何想法吗?甚至像国家名单这样的资源也可以逆转street1
并且street2
很有用。
解决方案
CNPostalAddressFormatter
有一个有趣的 API 可以获取NSAttributedString
其中标识每个地址组件的位置。您可以使用它来提取您想要的信息,例如街道,其中包括正确本地化的次干道和通道,无论它可能存在于邮政地址中的哪个位置。
let addressFormatter = CNPostalAddressFormatter()
let attributedAddress = addressFormatter.attributedString(from: postalAddress, withDefaultAttributes: [:])
let nsString = attributedAddress.string as NSString
let range = NSRange(location: 0, length: nsString.length)
var street: String?
attributedAddress.enumerateAttributes(in: range, options: []) { result, range, stop in
if let component = result[NSAttributedString.Key(CNPostalAddressPropertyAttribute)] as? String {
if component == CNPostalAddressStreetKey {
street = nsString.substring(with: range)
stop.pointee = true
}
}
}
我还向 Apple 提交了反馈,以添加更强大和更灵活的 API:FB8648023 Template API 希望用指定的组件格式化地址,类似于DateFormatter.setLocalizedDateFormatFromTemplate
推荐阅读
- python - 在项目中执行“npm install”时出现“gyp ERR!stack SyntaxError: invalid syntax:”
- ios - 获取请求中的令牌标头不起作用。生成错误 403 响应
- php - 查找字符串中第一个重复的单词
- .net-core - 为源重试“FindPackagesByIdAsync”
- intellij-idea - 错误:无法启动 javac.exe。exec:“javac.exe”:在 intellij 上运行仪表命令后,在 %PATH 中找不到可执行文件
- asp.net-core - 使用 AWS Cloudwatch 定期调用特定的 .net 核心 mvc 操作
- java - Android Recycler 分页:Room + RxJava + MVP
- python - 基于置信区间值的误差带等值线图
- icalendar - 使用 ical 文件取消事件
- python - 我如何解决''NoneType'对象不可下标'