Ottenere la lingua corrente del dispositivo in iOS?


431

Vorrei mostrare la lingua corrente utilizzata dall'interfaccia utente del dispositivo. Quale codice dovrei usare?

Lo voglio come un NSStringformato completamente spiegato. (Non @ "en_US")

EDIT: per coloro che guidano, ci sono un sacco di commenti utili qui, poiché la risposta si è evoluta con le nuove versioni di iOS.


1
Questo è integrato NSLocale. Vedi la mia risposta
Erik B,

15
Commento iOS9: presta attenzione al fatto che per qualche strana ragione, Apple ha cambiato il formato restituito [NSLocale preferredLanguages]. era separato da un trattino basso (ad es. en_US), ma ora è stato cambiato in un trattino:en-US
ishahak

7
Altro su iOS9: anche ottenere [NSLocale favoriteLanguages] su un simulatore iOS 8.4 rispetto al simulatore 9.0 ha delle discrepanze. Su iOS 8.4 è "en" e iOS 9.0 è "en-US"
Kris Subramanian

Questo commento mi ha aiutato molto! Siamo rimasti bloccati da un semplice problema che si chiedeva cosa fosse andato storto per circa 1 ora fino a quando non ho visto il tuo commento.
Thandasoru,

3
NSLocaleha metodi componentsFromLocaleIdentifier:e localeIdentifierFromComponents:che sono probabilmente il modo giusto per gestire il formato (potenzialmente modificabile).
Benjohn,

Risposte:


808

Le soluzioni fornite restituiranno effettivamente la regione corrente del dispositivo, non la lingua attualmente selezionata. Questi sono spesso la stessa cosa. Tuttavia, se mi trovo in Nord America e imposto la mia lingua su giapponese, la mia regione sarà ancora l'inglese (Stati Uniti). Per recuperare la lingua attualmente selezionata, puoi fare:

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

Ciò restituirà un codice di due lettere per la lingua attualmente selezionata. "en" per l'inglese, "es" per lo spagnolo, "de" per il tedesco, ecc. Per ulteriori esempi, vedere questa voce di Wikipedia (in particolare, la colonna 639-1):

Elenco dei codici ISO 639-1

Quindi si tratta semplicemente di convertire i due codici di lettere nella stringa che si desidera visualizzare. Quindi, se è "en", visualizza "English".

Spero che questo aiuti qualcuno che sta cercando di distinguere tra regione e lingua attualmente selezionata.

MODIFICARE

Vale la pena citare le informazioni di intestazione da 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

Le persone interessate al linguaggio delle app danno un'occhiata alla risposta di @ mindvision


2
Esattamente quello che stavo cercando. Ho avuto lo stesso problema in cui la regione non è la stessa della lingua.
Jasarien,

12
cattiva risposta: restituisce zh-Hans per il cinese, che non è il codice ISO.
cyrilchampier,

2
I primi due personaggi danno al paese, le cose dopo il trattino danno alla regione, il resto è solo per restringerlo ulteriormente (come i dialetti locali). zh è elencato come codice ISO per il cinese. Per chi cerca una lingua specifica come me, prova il registro IANA
Xono,

3
zh-Hans è l'unica eccezione o ci sono altri codici di lingua che differiscono dallo standard ISO 639-1?
MPaulo,

57
Attenzione: in iOS 9 , il valore di ritorno del èNSLocale preferredLanguagescambiato. Se prima hai ricevuto solo "en", in iOS 9 otterrai "en-US" o "en-JP", ecc. Riferimento: happyteamlabs.com/blog/…
Dj S

281

La risposta selezionata restituisce la lingua corrente del dispositivo, ma non la lingua effettiva utilizzata nell'app. Se non fornisci una localizzazione nella tua app per la lingua preferita dell'utente, viene utilizzata la prima localizzazione disponibile, ordinata in base all'ordine preferito dell'utente.

Per scoprire la lingua corrente selezionata all'interno delle tue localizzazioni usa

[[NSBundle mainBundle] preferredLocalizations];

Esempio:

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

Swift:

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

Eccellente, anche questo mi interessava. Testato e funziona correttamente!
smileyborg,

5
Perfetto! mi consente di costruire percorsi di risorse remote localizzati con solo le lingue supportate dalla mia app in ordine preferibile.
Yevhen Dubinin,

cosa succede se vogliamo ottenere il nome dell'intera lingua dopo questo?
Shabarinath Pabba,

Se si desidera ottenere l'intero nome della lingua dalla lingua preferita, è possibile utilizzare [[NSLocale alloc] initWithLocaleIdentifier: lingua] (dall'alto). Quindi hai le impostazioni internazionali e puoi chiamare displayNameForKey.
Vanessa Forney,

87

Soluzione per iOS 9:

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

language = "en-US"

NSDictionary *languageDic = [NSLocale componentsFromLocaleIdentifier:language];

languageDic avrà i componenti necessari

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

countryCode = "US"

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

languageCode = "en"


5
kCFLocaleLanguageCodeKey è una costante definita che puoi usare piuttosto che creare la tua stringa.
SNyamathi,

1
NSLocaleLanguageCode = @ "kCFLocaleCountryCodeKey"
crow

usa NSLocaleCountryCode e NSLocaleLanguageCode per @ "kCFLocaleCountryCodeKey", @ "kCFLocaleLanguageCodeKey", ripetutamente
crow

65

Questo probabilmente ti darà quello che vuoi:

NSLocale *locale = [NSLocale currentLocale];

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

Mostrerà il nome della lingua, nella lingua stessa. Per esempio:

Français (France)
English (United States)

31
risposta sbagliata: restituisce le
impostazioni

4
Questo è sicuramente sbagliato, ad esempio se si imposta la lingua nelle impostazioni del telefono su inglese e il formato della regione per dire tedesco, Germania, l'esempio sopra restituisce "tedesco". Tuttavia la lingua del telefono è impostata su inglese.
jake_hetfield,

2
Questo non è affatto sbagliato. Le impostazioni internazionali contengono informazioni sulla lingua e sulla regione. Quindi nell'esempio di @jake_hetfield non restituirebbe "Tedesco", restituirebbe "Inglese (Germania)". Questo combinato con la risposta di dreamlab dovrebbe essere la risposta corretta.
SeanR

36

avvertimentoLe risposte accettate e le altre non tengono conto del fatto che la lingua preferita può essere un'altra lingua rispetto alla lingua del dispositivo .

La lingua del dispositivo è la lingua in cui vengono presentati gli elementi del sistema operativo e le app Apple.

La lingua preferita è la lingua in cui l'utente vorrebbe localizzare le app. Apple fornisce solo un numero limitato di traduzioni. Se la lingua preferita è una lingua in cui Apple ha tradotto le sue app, sarà anche la lingua del dispositivo. Tuttavia, se l'utente preferisce una lingua per la quale Apple non fornisce traduzioni, il dispositivo e le lingue preferite non corrisponderanno . La lingua del dispositivo non sarà in prima posizione nell'elenco delle lingue preferite.

La seguente funzione passerà attraverso l'elenco delle lingue preferite e controllerà se esiste una traduzione nei framework Apple. La prima lingua per avere una traduzione è la lingua del dispositivo. La funzione restituirà il suo codice lingua.

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
}

Funziona se l'elenco delle lingue preferite è:

  1. afrikaans (iOS non è tradotto in afrikaans)
  2. Spagnolo (lingua del dispositivo)

L' elenco delle lingue preferite può essere modificato in : Settings.app -> Generale -> Lingua e regione -> Ordine lingue preferite


È quindi possibile utilizzare il codice lingua del dispositivo e tradurlo nel nome della lingua. Le seguenti righe stamperanno la lingua del dispositivo nella lingua del dispositivo. Ad esempio "Español" se il dispositivo è impostato su spagnolo.

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

La mia comprensione è che inizializzando l'istanza del bundle con NSBundle(forClass: UIView.self)si sta cercando di fornire la lingua più specifica per una determinata vista. Tuttavia, usando questo mi sono imbattuto in un problema in cui per la classe data non veniva restituita una lingua. Ho modificato l'inizializzazione NSBundle.mainBundle()e mi è stato restituito il codice lingua previsto.
palmi,

Chiarimento: inizializzazione del fascio con mainBundle()sembra essere quello raccomandato da Apple come suggerito nel intestazione per 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()restituisce il bundle dell'app, mentre NSBundle(forClass: UIView.self)restituisce il bundle UIKit dei sistemi. il metodo descritto cerca le directory nel bundle. il pacchetto dell'app conterrà solo quelli per le lingue in cui si intende localizzare. per determinare la lingua del dispositivo sarà necessario controllare il bundle di sistema.
dreamlab,

1
@Pouria il problema potrebbe essere che iOS 9 ha cambiato i valori di ritorno NSLocale.preferredLanguages(). ho aggiornato la risposta per supportare iOS 9 .
dreamlab,

@dreamlab sfortunatamente questo approccio fornisce risultati falsi positivi quando si includono componenti di terze parti, come i pod, con localizzazioni non supportate nelle impostazioni del progetto.
Kokoko,

12

lo uso

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

ignora la perdita di memoria ..

e il risultato è

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

solo per curiosità, dov'è la perdita di memoria qui?
Can Poyrazoğlu,

Perdita - [[[NSLocale alloc] initWithLocaleIdentifier: lan].
Pavel,

1
Solo per progetti non ARC, però.
Josh Hinman,

12

La traduzione di codici di lingua come en_US in inglese (Stati Uniti) è una funzionalità integrata NSLocalee NSLocalenon importa da dove si ottengono i codici di lingua. Quindi non c'è davvero alcun motivo per implementare la tua traduzione come suggerisce la risposta accettata.

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

Stampe: inglese, tedesco, svedese


1
In realtà, dovresti usare [NSLocale autoupdatingCurrentLocale] per inizializzare l'istanza della tua locale. In questo modo i nomi delle lingue verranno visualizzati nella lingua madre degli utenti. Ad esempio lo svedese diventerà Svenska.
Maciej Swic,

8

Anche c'è un modo migliore per ottenere la lingua corrente del dispositivo. Proviamo con il codice seguente -

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

Consigliato da Abizern su qui


7

Puoi usare il displayNameForKey:value:metodo di 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"]);

Questo stamperà:

français (France)
anglais tats-Unis)

Se specifichi lo stesso identificatore locale per il metodo initWithLocaleIdentifier:e anche per il displayNameForKey:value:metodo, ti darà il nome nativo della lingua. Ho scoperto che se rimuovi il prefisso internazionale e usi solo fre en, anche questo ometterà il paese dal nome visualizzato (almeno su Mac OS X, non sono sicuro di iOS).


6

veloce

Per ottenere la lingua corrente del dispositivo

NSLocale.preferredLanguages()[0] as String

Per ottenere la lingua dell'applicazione

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

Nota:

Recupera la lingua che hai fornito in CFBundleDevelopmentRegion di info.plist

se CFBundleAllowMixedLocalizations è true in info.plist, viene restituito il primo elemento di CFBundleLocalizations in info.plist


6

Ho cercato di trovare la soluzione giusta per me. Quando uso è Locale.preferredLanguages.firststata restituita la lingua preferita dalle impostazioni della tua app.

Se vuoi conoscere la lingua dalle impostazioni del dispositivo dell'utente, dovresti usare la stringa seguente:

Swift 3

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

Per scartare e usare guarda la riga qui sotto:

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

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

non devi scartarlo se usi Bundle.main.preferredLocalizations [0] come String
μολὼν.λαβέ

5

Per ottenere la lingua corrente del dispositivo dell'utente utilizzare il seguente codice esso ha funzionato per me.

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

4

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

Gli utenti possono selezionare la lingua preferita di un'app indipendentemente dalla lingua del sistema operativo.

Puoi usare questi:

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

Per gli sviluppatori di MonoTouch C # usare:

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

Nota: so che questa era una domanda iOS, ma poiché sono uno sviluppatore MonoTouch, la risposta in questa pagina mi ha portato nella giusta direzione e ho pensato di condividere i risultati.


Attualmente sto usando NSLocale.PreferredLanguages ​​e sto ottenendo un array vuoto. Presumo che tu abbia letto nella documentazione che potrebbe non essere mai vuoto ma non riesco a vederlo da nessuna parte?
JFoulkes,

No, onestamente era solo un mio presupposto.
Chuck Savage,

@LarryF Guarda questo video: jonas.follesoe.no/2011/07/22/cross-platform-mobile-ndc-2011 È molto istruttivo su come strutturare il tuo codice / app multipiattaforma.
Chuck Savage,

3

In Swift:

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

3

Swift 3

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

Benvenuto in Stack Overflow! Mentre questo pezzo di codice può rispondere alla domanda, è meglio includere una descrizione di quale fosse il problema e come il tuo codice affronterà il problema dato. Per il futuro, ecco alcune informazioni su come ottenere una risposta straordinaria su StackTranslate.it.
dirtydanee,

3

Semplice funzione 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

Se stai cercando il codice della lingua preferita ("en", "de", "es" ...) e il nome della lingua preferita localizzata (per la locale corrente), ecco una semplice estensione in 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

Se vuoi ottenere solo la lingua qui è la mia risposta suggerita:

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

Nel mio caso, volevo solo solo la lingua locale e non la regione locale.

Output: se la lingua della tua lingua locale è giapponese e la regione locale è il Giappone, allora:

langplusreg = ja-JP

langonly = ja


1

Risposta di @amir in Swift:

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

1

Ovviamente, le soluzioni si basano, ad esempio, su

[[NSLocale preferredLanguages] objectAtIndex:0]

di solito funziona bene e restituisce la lingua corrente del dispositivo.

Ma potrebbe essere fuorviante in alcuni casi:

Se l'app in cui vuoi ottenere questo valore ha già cambiato la lingua, ad esempio con questo tipo di codice:

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

In questo caso, [NSLocale favoriteLanguages] restituisce effettivamente la lingua preferita (e utilizzata) in questa particolare app, non la lingua corrente del dispositivo!

E ... in questo caso l'unico modo per ottenere correttamente l'attuale lingua del dispositivo (e non quella precedentemente impostata nell'app), è innanzitutto cancellare la chiave @ "appleLanguages" in NSUserDefaults, in questo modo:

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

Quindi, [NSLocale favoriteLanguages] ora restituisce il valore corretto.

Spero che questo aiuto.


1

Risposta aggiornata per Swift 4

let language = Bundle.main.preferredLocalizations.first

Si noti che questo recupera l'elenco aggregato delle localizzazioni disponibili (supportate dal bundle ovvero l'utente) e preferite (dall'utente). NSLocale.preferredLanguagesdovrebbe restituire quelli preferiti dall'utente senza pagare rispetto a ciò che è supportato dal pacchetto.
Jonny,

1

Per Swift 3.0 di seguito puoi usare il codice per rispondere alla tua domanda:

 let language = Bundle.main.preferredLocalizations.first! as NSString

1

In Swift 4.2 e Xcode 10.1

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

0

Secondo la documentazione Apple

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];


0

Per Swift 3:

NSLocale.preferredLanguages ​​[0] come String


0

A partire da iOS 9, se vuoi solo il codice della lingua senza il prefisso internazionale, vorrai questo tipo di funzione di supporto, poiché la lingua conterrà il prefisso internazionale.

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

Si noti che questo recupera l'elenco aggregato delle localizzazioni disponibili (supportate dal bundle ovvero l'utente) e preferite (dall'utente). NSLocale.preferredLanguagesdovrebbe restituire quelli preferiti dall'utente senza pagare rispetto a ciò che è supportato dal pacchetto.
Jonny,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.