Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get iOS current language (including country code)

I need to get a string like en_US or es_ES in iOS.

The obvious method is to use [NSLocale currentLocale] and get the language info from there. However, that gives you the "region format" and not the actual device language, which means that if you have the device language in english but the region format as "spain", it'll erroneously report es_ES.

If you need the device language you must do this instead: [[NSLocale preferredLanguages] objectAtIndex:0]

However, that only gives you the language, so you get something like en or es, without the country code at the end.

How would I get the country code correctly, like Safari does?

like image 431
hasvn Avatar asked Sep 09 '13 13:09

hasvn


People also ask

What is NSLocale?

An object representing information about linguistic, cultural, and technological conventions that bridges to Locale ; use NSLocale when you need reference semantics or other Foundation-specific behavior.

What is locale in IOS Swift?

Locale encapsulates information about linguistic, cultural, and technological conventions and standards.


2 Answers

Try with this code:

NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSRange startRange = [locale rangeOfString:@"_"];
NSString *result = [locale stringByReplacingCharactersInRange:NSMakeRange(0, startRange.length+1) withString:[[NSLocale preferredLanguages] objectAtIndex:0]];
DebugLog(@"current locale: %@", result);
like image 124
Manuel Escrig Avatar answered Oct 05 '22 00:10

Manuel Escrig


Ok, seeing getting the right info out of iOS is probably not possible, here's a hackish solution but which gives the output I needed. It's not complete and it won't give precise output in some cases (like for arabic), but it's the best I've been able to get.

const string lang = [[[NSLocale preferredLanguages] objectAtIndex:0] UTF8String];

// Search the language with country code in the langs map
static std::map<string, string> langMap;
static bool initialized = false;
if(!initialized) {
    #define LANG(l, c) langMap.insert(std::make_pair(#l, #c))

    LANG(en, en-us); LANG(es, es-es); LANG(fr, fr-fr); LANG(de, de-de);
    LANG(ja, ja-jp); LANG(nl, nl-nl); LANG(it, it-it); LANG(pt, pt-br);
    LANG(da, da-dk); LANG(fi, fi-fi); LANG(nb, nb-no); LANG(sv, sv-se);
    LANG(ko, ko-kr); LANG(ru, ru-ru); LANG(pl, pl-pl); LANG(tr, tr-tr);
    LANG(uk, uk-ua); LANG(hr, hr-hr); LANG(cs, cs-cz); LANG(el, el-gr);
    LANG(he, he-il); LANG(ro, ro-ro); LANG(sk, sk-sk); LANG(th, th-th);
    LANG(ca, ca-es); LANG(hu, hu-hu); LANG(vi, vi-vn);
    LANG(zh-Hans, zh-cn); LANG(pt-PT, pt-pt); LANG(id, id); LANG(ms, ms);
    LANG(zh-Hant, zh-tw); LANG(en-GB, en-gb); LANG(ar, ar);

    #undef LANG
    initialized = true;
}

map<string,string>::iterator it = langMap.find(lang);
if( it != langMap.end() ){
    return it->second;
}

// Didn't find a country code, default to the lang name
return lang;
like image 25
hasvn Avatar answered Oct 05 '22 02:10

hasvn