Asaf Baibekov
Asaf Baibekov

Reputation: 375

Swift - how to get ios device current language

My device running iOS 12 and has English language as its primary language and Hebrew as it's secondary language.

Now I'm opening my application with English as it's Base localization.

In the application I have list of three languages: English, Hebrew and French.

At first the attribute Locale.preferredLanguages result is: ["en-IL", "he-IL", "fr-IL"]

If I want to localize my entire application without to change the operating system language I'm changing only AppleLanguages array on UserDefaults like that:

func currentAppleLanguage() -> String {
    return (UserDefaults.standard.object(forKey: "AppleLanguages") as? NSArray)?
        .firstObject as? String ?? ""
}
func setAppleLanguageTo(lang: String) {
    UserDefaults.standard.set([lang], forKey: "AppleLanguages")
}

And after I make that change I'm restarting my application and the language changes.

The thing is after I change AppleLanguages at UserDefaults for example to "he", the Locale.preferredLanguages attribute turns into: ["he"]

So now I don't have the preferredLanguages fallback localizations that set on the operating system at the settings application.

Moreover, I'd like to now how can I get the current running device language on the operating system even after I change the application language with AppleLanguages like facebook does

Facebook localization screen

I'd like to mention I notice that when I edit the running scheme of Application Language to another language it changes the AppleLanguages as well.

Upvotes: 0

Views: 1942

Answers (1)

rmaddy
rmaddy

Reputation: 318804

Instead of replacing the array of "AppleLanguages" with just a single value, update the existing list so the specified language is moved to the top.

func currentAppleLanguage() -> String {
    return UserDefaults.standard.stringArray(forKey: "AppleLanguages")?.first ?? ""
}

func setAppleLanguageTo(lang: String) {
    // Get the current list
    var languages = UserDefaults.standard.stringArray(forKey: "AppleLanguages") ?? []
    // Get all locales using the specified language
    let matching = languages.filter { $0.hasPrefix(lang) }
    if matching.count > 0 {
        // Remove those entries from the list
        languages.removeAll { $0 == lang }
        // Add them back at the start of the list
        languages.insert(contentsOf: matching, at: 0)
    } else {
        // It wasn't found in the list so add it at the top
        languages.insert(lang, at: 0)
    }
    UserDefaults.standard.set(languages, forKey: "AppleLanguages")
}

This keeps the full list. It just reorders the values so the desired language is first.

Upvotes: 2

Related Questions