从国家名称获取国家代码在IOS中的实现

24

我正在从英语服务器检索国家名称,例如“西班牙”。

我想做的是,在假定国家名称将以英文编写的情况下,获取国家代码。

我该怎么做?我发现从国家代码获取国家名称相当容易,但我不知道如何进行相反的操作。

非常感谢。


你是如何从国家名称获取代码的?只需要做相反的操作 :) - deanWombourne
我希望这个链接能够帮到你:https://dev59.com/MXRB5IYBdhLWcg3wz6ad - Dilip Rajkumar
我已经检查过了,但我想要的是根据国家名称获取一个国家代码,而不是一系列国家。 - pdrcabrod
9个回答

30

Jef的答案在这里有所帮助,稍加补充即可。

NSArray *countryCodes = [NSLocale ISOCountryCodes];
NSMutableArray *countries = [NSMutableArray arrayWithCapacity:[countryCodes count]];

for (NSString *countryCode in countryCodes)
{
    NSString *identifier = [NSLocale localeIdentifierFromComponents: [NSDictionary dictionaryWithObject: countryCode forKey: NSLocaleCountryCode]];
    NSString *country = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_UK"] displayNameForKey: NSLocaleIdentifier value: identifier];
    [countries addObject: country];
}

NSDictionary *codeForCountryDictionary = [[NSDictionary alloc] initWithObjects:countryCodes forKeys:countries];

现在通过'codeForCountryDictionary'使用您需要代码的国家名称,例如:

NSLog(@"%@",[codeForCountryDictionary objectForKey:@"Spain"]);

这将得出结果为“ES”,它是西班牙的两个字母国家代码。


4
如果你知道国家名称是用英语写的,那么当然不应该使用当前语言环境(currentLocale),而应该使用固定的语言环境。因为当前语言环境可能是其他任何语言。可以使用[NSLocale initWithLocaleIdentifier:@"en_UK"]来代替。 - fishinear
initWithLocaleIdentifier是一个实例方法,而不是类方法,因此请使用[[NSLocale alloc] initWithLocaleIdentifier:@"en_UK"] - pyrou
为了确保,我还会将字典键转换为小写/大写。我们不确定服务器返回什么(这是另一个问题,但至少可以最小化“displayName”的弱点)。 - surui

15

@Daxesh Nagar的解决方案的Swift 4更新版本:

private func locale(for fullCountryName : String) -> String {
    var locales : String = ""
    for localeCode in NSLocale.isoCountryCodes {
        let identifier = NSLocale(localeIdentifier: localeCode)
        let countryName = identifier.displayName(forKey: NSLocale.Key.countryCode, value: localeCode)
        if fullCountryName.lowercased() == countryName?.lowercased() {
            return localeCode as! String
        }
    }
    return locales
}

将此输入作为 fullCountryName

"United Kingdom"

它将返回以下国家代码

"GB"

希望能对你们有所帮助!


这似乎只适用于英语环境,对吧?如果 fullCountryName 是 "Estados Unidos",有什么建议吗?好的解决方案,谢谢! - ArielSD
我建议更好的函数名称。它不返回区域设置,而是返回国家代码。 - rmaddy
请注意,此代码仅在国家名称以相应国家代码的适当语言表示时才有效。例如,“Spain”将不返回任何结果,但“España”将返回“ES”。 - rmaddy

4
在Swift中,您将使用以下代码。
extension NSLocale {
    class func locales1(countryName1 : String) -> String {
        var locales : String = ""
        for localeCode in NSLocale.ISOCountryCodes() {
            let countryName = NSLocale.systemLocale().displayNameForKey(NSLocaleCountryCode, value: localeCode)!
            if countryName1.lowercaseString == countryName.lowercaseString {
                return localeCode as! String
            }
        }
        return locales
    }


}

获取数据:

strP2countrycode = NSLocale.locales1("PASS_COUNTRYNAME")

2

使用 Swift 3 (上面的一些答案漏掉了一部分)

extension NSLocale {
class func locales1(countryName1 : String) -> String {
    let locales : String = ""
    for localeCode in NSLocale.isoCountryCodes {
        let countryName = (Locale.current as NSLocale).displayName(forKey: .countryCode, value: localeCode)
        if countryName1.lowercased() == countryName?.lowercased() {
            return localeCode
        }
    }
    return locales
}
}

为什么在Swift 3中创建一个NSLocale的扩展而不是Locale - rmaddy

2

我简化了版本并修复了只匹配英文国家名称问题。

extension NSLocale
{
    class func localeForCountry(countryName : String) -> String?
    {
        return NSLocale.ISOCountryCodes().first{self.countryNameFromLocaleCode($0 as! String) == countryName} as? String
    }

    private class func countryNameFromLocaleCode(localeCode : String) -> String
    {
        return NSLocale(localeIdentifier: "en_UK").displayNameForKey(NSLocaleCountryCode, value: localeCode) ?? ""
    }
}

我建议在您想确保标准英语名称和格式时使用特殊的en_US_POSIX区域设置。 - rmaddy

2

这里是一个简单的解决方案,适用于Swift 3或更高版本。根据您的操作系统版本,此方案支持大约256个国家名称和代码。

extension Locale {
    func isoCode(for countryName: String) -> String? {
        return Locale.isoRegionCodes.first(where: { (code) -> Bool in
            localizedString(forRegionCode: code)?.compare(countryName, options: [.caseInsensitive, .diacriticInsensitive]) == .orderedSame
        })
    }
}

正确使用此功能的诀窍在于了解您想要转换为标准2字母ISO国家代码的国家名称的语言。

如果您知道国家名称是英文的,则必须将其用于设置为英文的区域设置。在这种情况下最好使用特殊的区域设置en_US_POSIX

let locale = Locale(identifier: "en_US_POSIX") 
print(locale.isoCode(for: "Spain")) // result is `ES`

如果你的国家名称是用西班牙语书写的,那么一定要使用西班牙语环境。最初的回答。
let locale = Locale(identifier: "es") 
print(locale.isoCode(for: "España")) // result is `ES`

1

Swift 3.0 :

获取国家代码和国家名称作为NS字典 -

let countryCodes: [AnyObject] = NSLocale.isoCountryCodes as [AnyObject]

        let countries: NSMutableArray = NSMutableArray(capacity: countryCodes.count)

        for countryCode in countryCodes {
            let identifier: String = NSLocale.localeIdentifier(fromComponents: NSDictionary(object: countryCode, forKey: NSLocale.Key.countryCode as NSCopying) as! [String : String])
            let country: String = NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: identifier)!
            countries.add(country)
        }
        let codeForCountryDictionary: [NSObject : AnyObject] = NSDictionary(objects: countryCodes, forKeys: countries as! [NSCopying]) as [NSObject : AnyObject]

        print(codeForCountryDictionary)

为什么在Swift 3中所有NS类都存在? - rmaddy

0

所以这个解决方案在Swift 4中很好用,取自上面的评论...

extension NSLocale {
   struct Locale {
    let countryCode: String
    let countryName: String
   }

  class func locales() -> [Locale] {

    var locales = [Locale]()

    for localeCode in NSLocale.isoCountryCodes {
        let identifier = NSLocale(localeIdentifier: localeCode)
        let countryName = identifier.displayName(forKey: NSLocale.Key.countryCode, value: localeCode)!
        let countryCode = localeCode
        let locale = Locale(countryCode: countryCode, countryName: countryName)
        locales.append(locale)
    }

    return locales.sorted{$0.countryName.localizedCaseInsensitiveCompare($1.countryName) == ComparisonResult.orderedAscending}
 }
}

享受!


这并没有试图回答问题。而且在Swift中,你绝对不应该将一个结构体命名为“Locale”,因为“Locale”已经是Foundation提供的一个结构体。 - rmaddy

-1

Swift 5

extension Locale {
    func countryCode(by countryName: String) -> String? {
        return Locale.isoRegionCodes.first(where: { code -> Bool in
            guard let localizedCountryName = localizedString(forRegionCode: code) else {
                return false
            }
            return localizedCountryName.lowercased() == countryName.lowercased()
        })
    }
}

使用方法:

let locale = Locale(identifier: "en_US")
let countryCode = locale.countryCode(by: "Russia")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接