Question

Im retrieving a country name from a server in english. For example, "Spain"

What I want to do is, assuming the country name is going to be written in english, get the country code.

What should I do? I´ve found getting the country name from the country code quite easy, but I´ve got no idea of how to do the opposite operation.

Thanks a lot.

Was it helpful?

Solution

Jef's answer helped here, with slight additions.

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];

Now go through the 'codeForCountryDictionary' with the name of the country for which you require the code, for example,

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

would yield the result as 'ES', which is the 2 letter country code for spain.

OTHER TIPS

A Swift 4 updated version of @Daxesh Nagar solution:

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
}

For this Input as fullCountryName

"United Kingdom"

It will return the country code as follows

"GB"

Hope it helps you guys!

In the Swift you will use this code

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
    }


}

Get the data:

strP2countrycode = NSLocale.locales1("PASS_COUNTRYNAME")

My compact version including the fix for matching only against english country names version.

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) ?? ""
    }
}

In swift 3 you can just only use

let currentLocale = NSLocale.current
var countries = NSLocale.isoCountryCodes
currentLocale.localizedString(forRegionCode: countries.first!)

Using swift 3 (some of the answers above are missing a piece)

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.0 :

Getting the country code and country name as NS Dictionary-

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)

Here is a simple solution that works in Swift 3 or later. Depending on your OS version, this supports roughly 256 country names and codes.

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
        })
    }
}

The trick to using this correctly is knowing the language of the country names you wish to convert to the standard 2-letter ISO country code.

If you know the country names are in English, you must use this on a locale set to English. It would be best to use the special locale of en_US_POSIX in such a case.

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

If you have country names in Spanish, then be sure to use a Spanish locale:

let locale = Locale(identifier: "es") 
print(locale.isoCode(for: "España")) // result is `ES`

So this solution works well in swift 4 taken from comments above...

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}
 }
}

enjoy!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top