首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何本地化国际地址,特别是主干道和次干道

如何本地化国际地址,特别是主干道和次干道
EN

Stack Overflow用户
提问于 2020-03-31 11:39:00
回答 2查看 485关注 0票数 2

我正在开发一个大量使用不同国家地址的应用程序。我们有很多方法来输入它们,从导入地址,到在地图上放置大头针,以反向地理编码我们当前的位置。

我目前的项目是正确格式化国际地址:

在美国:

18 Street Name

在挪威:

Street Name 18

我已经想出了一堆用CLPlacemark实例化CNMutablePostalAddress的方法,以获得一些很好的结果,我遇到的问题是这样的。

我只想以一行字符串的形式返回街道名称和数字: So: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)

但这是超级老生常谈的,我相信它将打破像日本这样不同的邮寄地址顺序的国家。

目前,我甚至找不到任何资源来告诉我哪些国家撤销了subThoroughfarethoroughfare,因为如果我有一个这样的列表,我可以手动地撤销它。

以下是我到目前为止管理的一些示例代码:

代码语言:javascript
复制
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)
}

有什么想法吗?甚至像反向street1street2的国家列表这样的资源也是有用的。

EN

回答 2

Stack Overflow用户

发布于 2020-04-01 10:48:24

我最终采用了一种混合方法。

对于CNMutablePostalAddress()CLPlacemark来说,这是非常直接的:

cnPostalAddress.street = placemarker.postalAddress?.street

但是,这不适用于任何其他输入方法,并且不能修改为与CNMutablePostalAddress()不同的格式

当我需要手动从其他来源引入地址信息时,这里有一个适用于几个国家的示例:

代码语言:javascript
复制
static private func generateLocalizedStreetAddress(from adderss: MailingAddress) -> String {
    guard adderss.localizedStreet.isEmpty else { return adderss.localizedStreet ?? "" }

    let country = CountryCode.country(for: adderss.countryCode)
    let thoroughfare = adderss.thoroughfare ?? ""
    let subThoroughfare = adderss.subThoroughfare ?? ""
    let delimiter = self.generateDelimiter(from: thoroughfare, and: subThoroughfare, with: country)

    switch country {
    case .belgium, .czechRepublic, .denmark, .finland, .germany, .latvia, .netherlands, .norway, .poland, .portugal, .sweden:
        return thoroughfare + delimiter + subThoroughfare
    default:
        return subThoroughfare + delimiter + thoroughfare
    }
}

static private func generateDelimiter(from thoroughfare: String, and subThoroughfare: String, with country: Country) -> String {
    guard !thoroughfare.isEmpty && !subThoroughfare.isEmpty else { return "" }

    switch country {
    case .spain:
        return ", "
    default:
        return " "
    }
}
票数 0
EN

Stack Overflow用户

发布于 2020-09-08 04:16:39

CNPostalAddressFormatter有一个有趣的API来获取一个NSAttributedString,其中每个地址组件都是在其中标识的。您可以使用它来提取您想要的信息,比如街道,它包括适当本地化的子大道和大道,而不管它可能存在于邮政地址中的什么位置。

代码语言:javascript
复制
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
        }
    }
}

我还向苹果提交了反馈,希望添加一个更强大、更灵活的应用程序接口: FB8648023模板应用程序接口,用于格式化与DateFormatter.setLocalizedDateFormatFromTemplate类似的指定组件的地址

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60943079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档