获取iOS当前语言(包括国家代码)

11

我需要在iOS中获取像en_USes_ES这样的字符串。

明显的方法是使用[NSLocale currentLocale]并从那里获取语言信息。然而,它会给你“区域格式”,而不是实际的设备语言,这意味着如果你将设备语言设置为英语但区域格式为“西班牙”,它会错误地报告es_ES

如果你需要设备语言,你必须使用以下方法: [[NSLocale preferredLanguages] objectAtIndex:0]

然而,它只会给你语言,所以你会得到像enes这样的东西,没有结尾的国家代码。

如何正确地获取国家代码,就像Safari一样?

7个回答

3

试试这段代码:

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

正如我在问题中所解释的那样,currentLocale并不返回语言,而是区域格式。这意味着我可以将设备设置为英语,区域格式为加泰罗尼亚语(西班牙),然后即使整个设备都是英语,我也会得到ca_ES。然而,Safari在该设备上返回en_US,这是应该的。 - hasvn
1
@hasvn 我编辑了答案,不知道是否完全符合您的要求。但它确实显示了“language_region”,希望能对您有所帮助! - Manuel Escrig
不,那会将您的原始答案与@null的答案结合起来,但在这种情况下,它会返回“en_ES”,而不是Safari返回的逻辑上的“en_US” :-\ - hasvn

2

好的,看起来从iOS获取正确的信息可能不太可能,这里提供了一个hackish的解决方案,但它可以提供我需要的输出。它不完整,并且在某些情况下(比如阿拉伯语),它无法给出精确的输出,但这是我能够得到的最好的。

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;

1

Swift

NSLocale.preferredLanguages()[0] as String

输出将会是

en-GB

Source


1
请查看下面的代码:
NSArray *langs = [NSLocale preferredLanguages];
for (NSString *lang in langs) {
     NSLog(@"%@: %@ %@",lang, [NSLocale canonicalLanguageIdentifierFromString:lang],    [[[NSLocale alloc] initWithLocaleIdentifier:lang] displayNameForKey:NSLocaleIdentifier value:lang]);
}

1
这会打印出 "en: en English",而不是我需要的 "en_US"。 - hasvn
兄弟,[NSLocale canonicalLanguageIdentifierFromString:lang] 对我来说打印出 ar-QA。请再次确认一下。尝试手动设置语言为 en_US 并进行检查。 - Tarek Hallak
有一些地区确实显示了国家,但大多数地区并没有。这是使用您的代码得到的完整列表:https://gist.github.com/JonValdes/c9ff4e7b09d10222e9d1 如您所见,大多数语言环境都没有显示国家代码。 - hasvn
抱歉,但我认为这是您从iOS中可以获得的最大限度。 - Tarek Hallak

1
一个替代方案是从当前语言环境的组件中重建语言环境,并切换到所需的语言。
例如,要获取当前语言环境,但修改为使用UIKit当前用于显示应用程序的语言:
let languageCode = Bundle.main.preferredLocalizations.first ?? "en"
var components = Locale.components(fromIdentifier: Locale.current.identifier)
components[NSLocale.Key.languageCode.rawValue] = languageCode
let locale = Locale(identifier: Locale.identifier(fromComponents: components))

0

目前我正在使用这个。我已经运行了几个测试用例,看起来还可以,但是我并不认为它是一个稳健的解决方案。我很惊讶没有找到一个明确的答案来解决这个简单的问题。我不建议使用我的解决方案,但我希望它能引发讨论。

NSLocale *locale = [NSLocale currentLocale];
NSString *countryCode = [locale objectForKey: NSLocaleCountryCode];

NSString *language = [[NSLocale preferredLanguages] firstObject];
NSString *myLocale = [NSString stringWithFormat:@"%@_%@",language,countryCode];
NSLocale *userLocale = [[NSLocale alloc] initWithLocaleIdentifier:myLocale];

NSDate* now = [NSDate date];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:@"E MMM d yyyy HH:mm" options:0 locale:userLocale];

0

只需这样做:

NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *locale = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];

NSString *formattedStr = [NSString stringWithFormat:@"%@_%@",language, locale];
NSLog(@"%@", formattedStr); // Display en_US for example

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