在iOS中获取当前设备语言?


431

我想显示设备UI使用的当前语言。我将使用什么代码?

我希望这是NSString完全拼写的格式。(不是@“ en_US”)

编辑:对于那些继续前进的人,这里有大量有用的评论,因为答案随着新的iOS版本的发展而发展。


1
这是内置的NSLocale。看我的答案。
Erik B

15
iOS9评论:请注意以下事实:由于某些奇怪的原因,Apple更改了返回的格式[NSLocale preferredLanguages]。它以前用下划线分隔(例如en_US),但现在变成了破折号:en-US
ishahak

7
有关iOS9的更多信息:在iOS 8.4仿真器与9.0仿真器上获取[NSLocale preferredLanguages]也存在差异。在iOS 8.4上是“ en”,在iOS 9.0上是“ en-US”
Kris Subramanian

此评论对我有很大帮助!我们陷入一个简单的问题,想知道大约1个小时后出了什么问题,直到我看到您的评论。
thandasoru,2015年

3
NSLocale有一些方法componentsFromLocaleIdentifier:localeIdentifierFromComponents:这些方法可能是处理(可能可变的)格式的正确方法。
约翰

Answers:


808

提供的解决方案实际上将返回设备的当前区域,而不是当前选择的语言。这些通常是相同的。但是,如果我在北美,并且将语言设置为日语,则我的地区仍将是英语(美国)。为了检索当前选择的语言,您可以执行以下操作:

NSString * language = [[NSLocale preferredLanguages] firstObject];

这将返回当前所选语言的两个字母代码。“ en”代表英语,“ es”代表西班牙语,“ de”代表德语,等等。有关更多示例,请参见此Wikipedia条目(尤其是639-1列):

ISO 639-1代码列表

然后,只需将两个字母代码转换为您想要显示的字符串即可。因此,如果它是“ en”,则显示“ English”。

希望这对寻求区分地区和当前所选语言的人有所帮助。

编辑

值得引用NSLocale.h的标头信息:

+ (NSArray *)preferredLanguages NS_AVAILABLE(10_5, 2_0); // note that this list does not indicate what language the app is actually running in; the [NSBundle mainBundle] object determines that at launch and knows that information

对应用程序语言感兴趣的人可以看看@mindvision的答案


2
正是我想要的。在区域与语言不同的地方,我遇到了同样的问题。
Jasarien

12
错误答案:用中文返回zh-Hans,这不是iso代码。
cyrilchampier 2012年

2
前两个字符代表国家,破折号后面的东西代表区域,其余的只是用于进一步缩小范围(例如当地方言)。zh被列为中文的iso代码。对于那些像我一样正在寻找特定语言的人,请尝试IANA注册中心
Xono 2012年

3
zh-Hans是唯一的例外,还是其他语言代码与ISO 639-1标准不同?
MPaulo 2014年

57
警告:在iOS 9中NSLocale preferredLanguages更改的返回值。如果你已经得到之前“恩”而已,在iOS中9,你会得到“EN-US”或“EN-JP”等参考: happyteamlabs.com/blog/...
了Dj小号

281

所选答案返回当前设备语言,但不返回应用程序中使用的实际语言。如果您未在应用中提供用户首选语言的本地化版本,则会使用按用户首选顺序排序的第一个可用本地化版本。

要发现您的本地化语言中选择的当前语言,请使用

[[NSBundle mainBundle] preferredLocalizations];

例:

NSString *language = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];

迅速:

let language = NSBundle.mainBundle().preferredLocalizations.first as NSString

太好了,这也是我感兴趣的东西。经过测试,它可以正常工作!
smileyborg

5
完善!它允许我仅使用我的应用支持的语言来构建本地化的远程资源路径。
Yevhen Dubinin

如果要在此之后获得完整的语言名称怎么办?
Shabarinath Pabba

如果要从preferredLocalization获取完整的语言名称,则可以使用[[NSLocale alloc] initWithLocaleIdentifier:language](从上面)。这样便有了语言环境,可以调用displayNameForKey。
Vanessa Forney

87

iOS 9解决方案:

NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];

语言=“ zh-CN”

NSDictionary *languageDic = [NSLocale componentsFromLocaleIdentifier:language];

languageDic将具有所需的组件

NSString *countryCode = [languageDic objectForKey:@"kCFLocaleCountryCodeKey"];

countryCode =“美国”

NSString *languageCode = [languageDic objectForKey:@"kCFLocaleLanguageCodeKey"];

languageCode =“ en”


5
kCFLocaleLanguageCodeKey是您可以使用而不是创建自己的字符串的已定义常量。
SNyamathi '16

1
NSLocaleLanguageCode = @“ kCFLocaleCountryCodeKey”
乌鸦

将NSLocaleCountryCode和NSLocaleLanguageCode分别用于@“ kCFLocaleCountryCodeKey”,@“ kCFLocaleLanguageCodeKey”
乌鸦,

65

这可能会给您您想要的:

NSLocale *locale = [NSLocale currentLocale];

NSString *language = [locale displayNameForKey:NSLocaleIdentifier 
                                         value:[locale localeIdentifier]];

它会在语言本身中显示语言名称。例如:

Français (France)
English (United States)

31
错误的答案:这将返回区域设置,而不是语言,这可能会有所不同...
cyrilchampier 2012年

4
这绝对是错误的,例如,如果您将电话设置中的语言设置为英语,并将“地区”格式设置为“德语,德国”,则上面的示例将返回“德语”。电话语言仍设置为英语。
jake_hetfield

2
这根本没有错。语言环境包含语言和地区信息。因此,在@jake_hetfield的示例中,它不会返回“德语”,而是将返回“英语(德国)”。结合dreamlab的答案应该是正确的答案。
SeanR

36

警告接受的答案和其他答案都没有考虑到首选语言可以是设备语言之外的另一种语言

所述设备的语言是在其中操作系统元件和苹果的应用程序呈现的语言。

首选语言是用户想要在苹果只提供了一组有限的翻译本地化的应用程序的语言。如果首选语言是Apple将其应用程序翻译成的一种语言,则它将也是设备语言。但是,如果用户喜欢Apple不提供翻译的语言,则设备和首选语言将不匹配。设备语言将不在首选语言列表中的第一位。

以下功能将遍历首选语言列表,并检查Apple框架中是否有翻译。可以翻译的第一种语言是设备语言。该函数将返回其语言代码。

func deviceLanguage() -> String? {
    let systemBundle: NSBundle = NSBundle(forClass: UIView.self)
    let englishLocale: NSLocale = NSLocale(localeIdentifier: "en")

    let preferredLanguages: [String] = NSLocale.preferredLanguages()

    for language: String in preferredLanguages {
        let languageComponents: [String : String] = NSLocale.componentsFromLocaleIdentifier(language)

        guard let languageCode: String = languageComponents[NSLocaleLanguageCode] else {
            continue
        }

        // ex: es_MX.lproj, zh_CN.lproj
        if let countryCode: String = languageComponents[NSLocaleCountryCode] {
            if systemBundle.pathForResource("\(languageCode)_\(countryCode)", ofType: "lproj") != nil {
                // returns language and country code because it appears that the actual language is coded within the country code aswell
                // for example: zh_CN probably mandarin, zh_HK probably cantonese
                return language
            }
        }

        // ex: English.lproj, German.lproj
        if let languageName: String = englishLocale.displayNameForKey(NSLocaleIdentifier, value: languageCode) {
            if systemBundle.pathForResource(languageName, ofType: "lproj") != nil {
                return languageCode
            }
        }

        // ex: pt.lproj, hu.lproj
        if systemBundle.pathForResource(languageCode, ofType: "lproj") != nil {
            return languageCode
        }
    }

    return nil
}

如果首选语言列表为:

  1. 南非荷兰语(iOS并未翻译成南非荷兰语)
  2. 西班牙语(设备语言)

首选语言列表,可以在编辑:Settings.app - >常规- >语言和区域选项- >首选语言的词序


然后,您可以使用设备语言代码并将其翻译为语言名称。以下各行将以设备语言打印设备语言。如果设备设置为西班牙语,例如“Español”。

if let deviceLanguageCode: String = deviceLanguage() {
    let printOutputLanguageCode: String = deviceLanguageCode
    let printOutputLocale: NSLocale = NSLocale(localeIdentifier: printOutputLanguageCode)

    if let deviceLanguageName: String = printOutputLocale.displayNameForKey(NSLocaleIdentifier, value: deviceLanguageCode) {
        // keep in mind that for some localizations this will print a language and a country
        // see deviceLanguage() implementation above
        print(deviceLanguageName)
    }
} 

我的理解是,通过初始化您的bundle实例,NSBundle(forClass: UIView.self)您尝试为给定视图提供最特定的语言。但是,使用这个我遇到了一个问题,对于给定的类,该语言没有返回。我将初始化更改为,NSBundle.mainBundle()并返回了预期的语言代码。
palmi

澄清:与初始化束mainBundle()似乎是一个由苹果推荐作为用于报头建议NSLocale// note that this list does not indicate what language the app is actually running in; the [NSBundle mainBundle] object determines that at launch and knows that information
palmi

@Pouria NSBundle.mainBundle()返回您的应用程序包,而NSBundle(forClass: UIView.self)返回系统UIKit包。所描述的方法在捆绑软件中查找目录。您的应用捆绑包将仅包含您打算本地化的语言。确定设备语言后,您需要检查系统捆绑包。
dreamlab

1
@Pouria问题可能是iOS 9更改了的返回值NSLocale.preferredLanguages()。我更新了答案以支持iOS 9
dreamlab

不幸的是,@ dreamlab在包含项目设置中不支持的本地化的第三方组件(例如pod)时,这种方法会给出假阳性结果。
kokoko

12

我用这个

    NSArray *arr = [NSLocale preferredLanguages];
for (NSString *lan in arr) {
    NSLog(@"%@: %@ %@",lan, [NSLocale canonicalLanguageIdentifierFromString:lan], [[[NSLocale alloc] initWithLocaleIdentifier:lan] displayNameForKey:NSLocaleIdentifier value:lan]);
}

忽略内存泄漏。

结果是

2013-03-02 20:01:57.457 xx[12334:907] zh-Hans: zh-Hans 中文(简体中文)
2013-03-02 20:01:57.460 xx[12334:907] en: en English
2013-03-02 20:01:57.462 xx[12334:907] ja: ja 日本語
2013-03-02 20:01:57.465 xx[12334:907] fr: fr français
2013-03-02 20:01:57.468 xx[12334:907] de: de Deutsch
2013-03-02 20:01:57.472 xx[12334:907] nl: nl Nederlands
2013-03-02 20:01:57.477 xx[12334:907] it: it italiano
2013-03-02 20:01:57.481 xx[12334:907] es: es español

只是出于好奇,这里的内存泄漏在哪里?
CanPoyrazoğlu2014年

泄漏-[[[[NSLocale alloc] initWithLocaleIdentifier:lan]。
帕维尔2014年

1
不过,仅适用于非ARC项目。
Josh Hinman

12

翻译语言代码,如EN_US英语(美国)是一个内置在功能NSLocaleNSLocale不关心你在哪里得到的语言代码。因此,确实没有理由按照已接受的答案进行自己的翻译。

// Example code - try changing the language codes and see what happens
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
NSString *l1 = [locale displayNameForKey:NSLocaleIdentifier value:@"en"];
NSString *l2 = [locale displayNameForKey:NSLocaleIdentifier value:@"de"];
NSString *l3 = [locale displayNameForKey:NSLocaleIdentifier value:@"sv"];
NSLog(@"%@, %@, %@", l1, l2, l3);

印刷品:英语,德语,瑞典语


1
实际上,您应该使用[NSLocale autoupdatingCurrentLocale]初始化您的语言环境实例。这样,语言名称将以用户的母语显示。例如,瑞典人将成为Svenska。
Maciej Swic 2014年

8

甚至还有更好的方法来获取当前的设备语言。让我们通过以下代码进行尝试-

NSLog(@"Current Language - %@", [[NSLocale preferredLanguages] firstObject]);

Abizern这里建议


7

您可以使用以下displayNameForKey:value:方法NSLocale

// get a French locale instance
NSLocale *frLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"] autorelease];

// use it to get translated display names of fr_FR and en_US
NSLog(@"%@", [frLocale displayNameForKey:NSLocaleIdentifier value:@"fr_FR"]);
NSLog(@"%@", [frLocale displayNameForKey:NSLocaleIdentifier value:@"en_US"]);

这将打印出:

français (France)
anglais tats-Unis)

如果您为initWithLocaleIdentifier:displayNameForKey:value:方法指定了相同的语言环境标识符,那么它将为您提供语言的本地名称。我发现如果删除国家/地区代码并仅使用fren,则它也会从显示名称中省略国家(至少在Mac OS X上,不确定iOS)。


6

迅速

获取设备的当前语言

NSLocale.preferredLanguages()[0] as String

获取应用语言

NSBundle.mainBundle().preferredLocalizations[0] as NSString

注意:

它获取您在info.plist的CFBundleDevelopmentRegion中指定的语言

如果info.plist中的CFBundleAllowMixedLocalizations为true,则返回info.plist中的CFBundleLocalizations的第一项


6

我试图为自己找到正确的解决方案。Locale.preferredLanguages.first从您的应用设置中返回了我使用时的首选语言。

如果要从用户设备设置中了解语言,则应使用以下使用字符串:

迅捷3

let currentDeviceLanguage = Locale.current.languageCode
// Will return the optional String

要展开和使用,请查看以下行:

if let currentDeviceLanguage = Locale.current.languageCode {
    print("currentLanguage", currentDeviceLanguage)

    // For example
    if currentDeviceLanguage == "he" {
        UIView.appearance().semanticContentAttribute = .forceRightToLeft
    } else {
        UIView.appearance().semanticContentAttribute = .forceLeftToRight
    }
}

您不需要;如果使用此Bundle.main.preferredLocalizations [0]作为String
不必拆包–μολὼν.λαβέ17年

5

为了获得用户设备当前的语言,请使用以下代码对我有用。

NSString * myString = [[NSLocale preferredlanguage]objectAtIndex:0];

4

iOS13,Swift 5 +,WWDC2019 https://developer.apple.com/videos/play/wwdc2019/403/

用户可以独立于OS语言选择应用程序的首选语言。

您可以使用这些:

    // Returns a list of the user's preferred languages.
    // Maybe more than (or none of) your app supports!
    Locale.preferredLanguages

    // a subset of this bundle's localizations, re-ordered into the preferred order
    // for this process's current execution environment; the main bundle's preferred localizations
    // indicate the language (of text) the user is most likely seeing in the UI
    Bundle.main.preferredLocalizations



    // The current running app language
    Bundle.main.preferredLocalizations.first

    // list of language names this bundle appears to be localized to
    Bundle.main.localizations

3

对于MonoTouch C#开发人员,请使用:

NSLocale.PreferredLanguages.FirstOrDefault() ?? "en"

注意:我知道这是一个iOS问题,但是由于我是MonoTouch开发人员,因此此页面上的答案将我引向了正确的方向,我认为我应该分享结果。


我目前正在使用NSLocale.PreferredLanguages,并且得到一个空数组。我认为您已经在文档中阅读到它可能永远不会为空,但是我在任何地方都看不到?
JFoulkes

不,说实话,这只是我自己的一个假设。
Chuck Savage 2012年

@LarryF观看此视频:jonas.follesoe.no/2011/07/22/cross-platform-mobile-ndc-2011 有关如何构建代码/多平台应用程序的信息非常丰富。
Chuck Savage 2012年

3

Swift

let languageCode = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode) as? String

3

迅捷3

let locale = Locale.current
let code = (locale as NSLocale).object(forKey: NSLocale.Key.countryCode) as! String?
print(code!)

欢迎使用Stack Overflow!尽管这段代码可以回答问题,但最好包含对问题所在以及代码如何解决给定问题的描述。对于将来,这里有一些信息,如何在Stack Overflow上给出一个很棒的答案
–dirddanee

3

简单的Swift 3功能:

  @discardableResult
  func getLanguageISO() -> String {
    let locale = Locale.current
    guard let languageCode = locale.languageCode,
          let regionCode = locale.regionCode else {
        return "de_DE"
    }
    return languageCode + "_" + regionCode
  }

3

如果您要查找首选语言代码(“ en”,“ de”,“ es” ...)和本地化的首选语言名称(对于当前语言环境),这是Swift中的一个简单扩展:

extension Locale {
static var preferredLanguageIdentifier: String {
    let id = Locale.preferredLanguages.first!
    let comps = Locale.components(fromIdentifier: id)
    return comps.values.first!
}

static var preferredLanguageLocalizedString: String {
    let id = Locale.preferredLanguages.first!
    return Locale.current.localizedString(forLanguageCode: id)!
}

}


2
-(NSString *)returnPreferredLanguage { //as written text

NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSArray *preferredLanguages = [defaults objectForKey:@"AppleLanguages"];
NSString *preferredLanguageCode = [preferredLanguages objectAtIndex:0]; //preferred device language code
NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"]; //language name will be in English (or whatever)
NSString *languageName = [enLocale displayNameForKey:NSLocaleIdentifier value:preferredLanguageCode]; //name of language, eg. "French"
return languageName;

}

2

如果您只想获得语言,这是我建议的答案:

NSString *langplusreg = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString * langonly = [[langplusreg componentsSeparatedByString:@"-"] 
objectAtIndex:0];

就我而言,我只希望使用语言环境语言,而不是语言环境区域。

输出:如果您的语言环境语言是日语,而语言环境地区是日本,那么:

langplusreg = ja-JP

langonly = ja


1

Swift中的@amir响应:

// Get language prefered by user
    let langageRegion = NSLocale.preferredLanguages().first!
    let languageDic = NSLocale.componentsFromLocaleIdentifier(langageRegion)
    let language = languageDic[NSLocaleLanguageCode]

1

显然,解决方案依赖于例如

[[NSLocale preferredLanguages] objectAtIndex:0]

通常可以正常工作并返回当前的设备语言。

但这在某些情况下可能会产生误导:

如果您要在其中获取此值的应用程序已经更改了语言,例如使用以下代码:

NSString *lg = @"en"; // or anything like @"en", @"fr", etc.
[[NSUserDefaults standardUserDefaults] 
    setObject:[NSArray arrayWithObjects:lg, nil]  
    forKey:@"AppleLanguages"]

在这种情况下,[NSLocale preferredLanguages] 实际上返回此特定应用程序中设置(和使用)的首选语言,而不是当前的设备语言!

并且...在这种情况下,正确获取实际当前设备语言(而不是先前在应用程序中设置的语言)的唯一方法是,首先清除NSUserDefaults中的键@“ appleLanguages”,如下所示:

[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"AppleLanguages"];

然后,[NSLocale preferredLanguages]现在返回正确的值。

希望能有所帮助。


1

更新了Swift 4的答案

let language = Bundle.main.preferredLocalizations.first

请注意,这会获取可用(由捆绑软件支持,即您)和首选(由用户)本地化的汇总列表。 NSLocale.preferredLanguages应该在不考虑捆绑软件支持的内容的情况下返回用户的首选参数。
Jonny


1

在Swift 4.2和Xcode 10.1中

let language = NSLocale.preferredLanguages[0]
print(language)//en



0

对于Swift 3:

NSLocale.preferredLanguages [0]作为字符串


0

从iOS 9开始,如果您只需要语言代码而不包含国家/地区代码,则需要这种帮助功能-因为该语言将包含国家/地区代码。

// gets the language code without country code in uppercase format, i.e. EN or DE
NSString* GetLanguageCode()
{
    static dispatch_once_t onceToken;
    static NSString* lang;
    dispatch_once(&onceToken, ^
    {
        lang = [[[NSLocale preferredLanguages] objectAtIndex:0] uppercaseString];
        NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"^[A-Za-z]+" options:0 error:nil];
        NSTextCheckingResult* match = [regex firstMatchInString:lang options:0 range:NSMakeRange(0, lang.length)];
        if (match.range.location != NSNotFound)
        {
            lang = [lang substringToIndex:match.range.length];
        }
    });
    return lang;
}

0

SWIFT-4

 // To get device default selected language. It will print like short name of zone. For english, en or spain, es.



let language = Bundle.main.preferredLocalizations.first! as NSString
    print("device language",language)

请注意,这会获取可用(由捆绑软件支持,即您)和首选(由用户)本地化的汇总列表。 NSLocale.preferredLanguages应该在不考虑捆绑软件支持的内容的情况下返回用户的首选参数。
Jonny
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.