user3739367
user3739367

Reputation: 4451

How to get current language code with Swift?

I want get the language code of the device (en, es...) in my app written with Swift. How can get this?

I'm trying this:

var preferredLanguages : NSLocale!
let pre = preferredLanguages.displayNameForKey(NSLocaleIdentifier, value: preferredLanguages)

But this returns nil.

Upvotes: 221

Views: 222317

Answers (21)

Obrienser
Obrienser

Reputation: 29

languageCode is deprecated.

'languageCode' was deprecated in iOS 16: renamed to 'language.languageCode.identifier'

Now we need to use:

Locale.current.language.languageCode?.identifier

Example:

if let languageCode = Locale.current.language.languageCode?.identifier {
    parameters["interface_language"] = languageCode
}

Upvotes: -1

Mitul Pokiya
Mitul Pokiya

Reputation: 172

In iOS 16 or later, you can get the device language code using the following method:

if #available(iOS 16.0, *) {
    let deviceLanguageCode = Locale.current.language.languageCode?.identifier
} else {
    let deviceLanguageCode = Locale.current.languageCode
}

Upvotes: 0

Viktor Golubenkov
Viktor Golubenkov

Reputation: 143

it may be useful to someone (Swift 5.10)

let currentLanguage = Locale.preferredLanguages[0] 
// returns 'en-TH' where 'en' preferred language code on the device, 'TH' location
// !!! note that the user can manually change the location

let languageCode = Locale.current.language.languageCode!.identifier
// returns 'en' 

Upvotes: 0

Boris Nikolic
Boris Nikolic

Reputation: 756

Almost none of the answers are correct. This is a working Swift 5.7 solution. ""

extension Locale {
    // Gets the language of the device, had to remove the content of AppleLanguages since `preferredLanguages`
    // is combining the result from multiple APIs. AppleLanguage is then set to the old value
    static var preferredLanguageCode: String {
        let appleLanguages = UserDefaults.standard.stringArray(forKey: "AppleLanguages")
        UserDefaults.standard.removeObject(forKey: "AppleLanguages")

        guard let preferredLanguage = preferredLanguages.first,
              let code = Locale(identifier: preferredLanguage).languageCode else {
            UserDefaults.standard.set(appleLanguages, forKey: "AppleLanguages")
            return "en"
        }
        UserDefaults.standard.set(appleLanguages, forKey: "AppleLanguages")
        return code
    }
}

Upvotes: 0

Supapon Pick Pucknavin
Supapon Pick Pucknavin

Reputation: 493

var languageCode = ""
 if #available(iOS 16.0, *) {
   if let language = NSLocale.current.language.languageCode {
     languageCode = language.identifier
   }
 } else {
   if let language = NSLocale.current.languageCode {
     languageCode = language
   }
 }

Upvotes: 2

Peter Lapisu
Peter Lapisu

Reputation: 20975

in most cases you want to get the language code of the current app UI, to send over an API to get localized response

extension Bundle {
    
    var currentLocalizedUILanguageCode: String {
        guard let code = Bundle.main.preferredLocalizations.first?.components(separatedBy: "-").first else {
            return Locale.current.languageCode ?? "en"
        }
        return code
    }
    
}

use like

headers["X-Language"] = Bundle.main.currentLocalizedUILanguageCode

Upvotes: 3

ChikabuZ
ChikabuZ

Reputation: 10185

Locale.current.languageCode returns me wrong code, so I use these extensions:

extension Locale {
    static var preferredLanguageCode: String {
        guard let preferredLanguage = preferredLanguages.first,
              let code = Locale(identifier: preferredLanguage).languageCode else {
            return "en"
        }
        return code
    }
    
    static var preferredLanguageCodes: [String] {
        return Locale.preferredLanguages.compactMap({Locale(identifier: $0).languageCode})
    }
}

Upvotes: 14

Alagu Raja.B
Alagu Raja.B

Reputation: 1

use this function for get your system's current language code from iOS devices

    func getSystemLanguageCode() -> String {
    UserDefaults.standard.removeObject(forKey: "AppleLanguages")
    let pref_Language = NSLocale.preferredLanguages[0] as String //"fr-IN"
    let language = pref_Language.components(separatedBy: "-") //["fr","IN"]
    let lang_Code = language.first?.lowercased() ?? "" //"fr"
    UserDefaults.standard.set([lang_Code], forKey: "AppleLanguages")
    
    return lang_Code
}

Upvotes: -2

Makwan Barzan
Makwan Barzan

Reputation: 394

Swift 5.4:

let languagePrefix = Locale.preferredLanguages[0]
print(languagePrefix)

Upvotes: 15

Johannes Fahrenkrug
Johannes Fahrenkrug

Reputation: 44740

TL;DR:

Use Bundle.main.preferredLocalizations[0] to get the language your app's UI is currently displayed in. Don't use Locale.current because it describes the region format (time, currency, distance, etc) and has nothing to do with language.

Detailed Answer:

The definite answer about how to get the language(!) code for the language your app's UI is displayed in comes from Apple engineer Quinn "The Eskimo", and I quote/paraphrase for Swift:

Locale.current returns the current locale, that is, the value set by Settings > General > Language & Region > Region Formats. It has nothing to do with the language that your app is running in. It's perfectly reasonable, and in fact quite common, for users in the field to have their locale and language set to 'conflicting' values. For example, a native English speaker living in France would have the language set to English but might choose to set the locale to French (so they get metric weights and measures, 24 time, and so on).

The language that your app runs in is determined by the language setting, that is, Settings > General > Language & Region > Preferred Language Order. When the system runs your app it takes this list of languages (the preferred list) and matches it against the list of languages that your app is localised into (the app list). The first language in the preferred list that exists in the app list is the language chosen for the app. This is what you'll find in the first entry of the main bundle's preferredLocalizations array.

Language Name from Code

To get the human-readable name of a language from its code, you can use this:

let langCode = Bundle.main.preferredLocalizations[0]
let usLocale = Locale(identifier: "en-US")
var langName = ""
if let languageName = usLocale.localizedString(forLanguageCode: langCode) {
    langName = languageName
}
        

This will give you the English name of the current UI language.

Upvotes: 75

Brian M
Brian M

Reputation: 419

This is what I use in Swift 5 Xcode 11:

Inside the class variables:

let languagePrefix = Bundle.main.preferredLocalizations.first?.prefix(2)

This comes as a string. It returns 2 characters, i.e. "en", "es", "de"...

From this I can easily determine what language to display:

 if languagePrefix == "es" { self.flipCard.setTitle("última carta", for: .normal) }
 if languagePrefix == "en" { self.flipCard.setTitle("Last Card", for: .normal) }

If you want the full information of the language, then remove ?.prefex(2)

Upvotes: 5

raed
raed

Reputation: 5075

It's important to make the difference between the App language and the device locale language (The code below is in Swift 3)

Will return the Device language:

let locale = NSLocale.current.languageCode

Will return the App language:

let pre = Locale.preferredLanguages[0]

Upvotes: 143

Bogdan Bystritskiy
Bogdan Bystritskiy

Reputation: 1333

Swift 4 & 5:

Locale.current.languageCode

Upvotes: 72

Bassant Ashraf
Bassant Ashraf

Reputation: 1609

swift 3

let preferredLanguage = Locale.preferredLanguages[0] as String
print (preferredLanguage) //en-US

let arr = preferredLanguage.components(separatedBy: "-")
let deviceLanguage = arr.first
print (deviceLanguage) //en

Upvotes: 23

Ali Ihsan URAL
Ali Ihsan URAL

Reputation: 1974

Swift 3 & 4 & 4.2 & 5

Locale.current.languageCode does not compile regularly. Because you did not implemented localization for your project.

You have two possible solutions

1) String(Locale.preferredLanguages[0].prefix(2)) It returns phone lang properly.

If you want to get the type en-En, you can use Locale.preferredLanguages[0]

2) Select Project(MyApp)->Project (not Target)-> press + button into Localizations, then add language which you want.

Upvotes: 49

yo2bh
yo2bh

Reputation: 1436

In Swift, You can get the locale using.

let locale = Locale.current.identifier

Upvotes: 6

Miniapps
Miniapps

Reputation: 292

I want to track the language chosen by the user in Settings app every time the user launches my app - that is not yet localized (my app is in English only). I adopted this logic:

  1. create an enum to to make it easier to handle the languages in array

    enum Language: String {
    
    case none = ""
    case en = "English"
    case fr = "French"
    case it = "Italian"
    
    } // add as many languages you want
    
  2. create a couple of extension to Locale

    extension Locale {
    
        static var enLocale: Locale {
    
            return Locale(identifier: "en-EN")
        } // to use in **currentLanguage** to get the localizedString in English
    
        static var currentLanguage: Language? {
    
            guard let code = preferredLanguages.first?.components(separatedBy: "-").last else {
    
                print("could not detect language code")
    
                return nil
            }
    
            guard let rawValue = enLocale.localizedString(forLanguageCode: code) else {
    
                print("could not localize language code")
    
                return nil
            }
    
            guard let language = Language(rawValue: rawValue) else {
    
                print("could not init language from raw value")
    
                return nil
            }
            print("language: \(code)-\(rawValue)")
    
            return language
        }
    }
    
  3. When you need, you can simply use the extension

    if let currentLanguage = Locale.currentLanguage {
        print(currentLanguage.rawValue)
        // Your code here.
    }
    

Upvotes: 6

Amr Angry
Amr Angry

Reputation: 3831

you may use the below code it works fine with swift 3

var preferredLanguage : String = Bundle.main.preferredLocalizations.first!

Upvotes: 10

Vadim Motorine
Vadim Motorine

Reputation: 3069

In Swift 3

let langStr = Locale.current.languageCode

Upvotes: 251

mazorati
mazorati

Reputation: 2071

In Swift 3:

NSLocale.current.languageCode

Upvotes: 40

Benknopf
Benknopf

Reputation: 422

To get current language used in your app (different than preferred languages)

NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)!

Upvotes: 34

Related Questions