Swift - how to get ios device current language - ios

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

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.

Related

Cannot access localized resource from app extension

I'm having trouble accessing localized resources from my Intents extension.
I've got a couple of JSON files that are localized into different languages in a framework that's shared between my app and the extension. When I access them though my app via path(forResource:ofType), it accesses the proper localized version, but if I call it from the extension in the Shortcuts app, then it returns the English, even if both the app itself and the Shortcuts app are both set to another language.
The only way I can get the correct language to appear is if I change the device language - changing it just for the app or for Shortcuts doesn't have an effect.
I'm building with the iOS 14 SDK, but the same behavior occurs on both iOS 13 and 14.
Firstly, please check Target Membership of Localizable file, make sure it was checked your extension.
Secondly, save your app language in UserDefaults which have AppGroups.
static func setLanguageExtension(_ language: String, forKey: String) {
if let userDefault = UserDefaults(suiteName: "APP_LANGUAGE") {
userDefault.setValue(language, forKey: forKey)
}
}
static func getLanguageExtension(key: String) -> String? {
if let userDefault = UserDefaults(suiteName: "APP_LANGUAGE") {
return userDefault.string(forKey: key)
} else {
return "en-US"
}
}

Localisation Settings Not Changing the System Defined Text in Swift 4.2

I have 2 lang support for my app
1) English - en
2) German - de
I have done all the procedures for localization, the only issue is
whenever I change the language from "en" to "de" or vice versa then
after the system text is not changing to the latest lang, but it
reflects when I kill the app and reopen it.
For Example:
The popover Copy-LookUp-Share is not localsied to German Lang. but the other things from .string file are lcoalised properly.
My change lang code:
func setLanguage(languageCode:String) {
var appleLanguages = UserDefaults.standard.object(forKey: "AppleLanguages") as! [String]
appleLanguages.remove(at: 0)
appleLanguages.insert(languageCode, at: 0)
UserDefaults.standard.set(appleLanguages, forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
if let languageDirectoryPath = Bundle.main.path(forResource: languageCode, ofType: "lproj") {
bundle = Bundle.init(path: languageDirectoryPath)
} else {
resetLocalization()
}
}
func resetLocalization() {
bundle = Bundle.main
}
FYI: Similar thing happens in 'WeChat' iOS application.
Those are UIKit SDK private menu items and you cannot control them, probably they are just created once then kept cached.
The only thing you can try is to force update in the moment of language change, like
UIMenuController.shared.update()
Note: actually using "AppleLanguages" key for that purpose is not documented, so it is kind of hucky. L10N is system settings originated feature, by design.

Localized text not showing for Privacy alert in iOS

I am developing an iOS application which supports English and Arabic. User can change the application language from inside the app.
When user changes the language I am setting it like ,
//change app language
UserDefaults.standard.set([language], forKey: "AppleLanguages")
currentLanguage = language
UserDefaults.standard.synchronize()
//current language updating
var currentLanguage : String{
get{
if let selectedLanguage = UserDefaults.standard.string(forKey: "selectedLanguage"){
return selectedLanguage
}else{
let language = Locale.preferredLanguages[0]
if language.hasPrefix("ar"){
return SupportedLanguage.ar.rawValue
}else{
return SupportedLanguage.en.rawValue
}
}
}
set{
UserDefaults.standard.setValue(newValue, forKey: "selectedLanguage")
}
}
In this way, App is not exiting. Just reloading the root view controller
The issue I am facing is, when I change the application language like this, the privacy alerts like “..requesting permission for using Location”, “… would ,like to use Photo album” etc are not showing in the selected language. I have created InfoPlist.string files for English and Arabic and added like
NSCameraUsageDescription = ".... would like to access Camera";
NSLocationAlwaysAndWhenInUseUsageDescription = ".... wants to use your current location for better usability";
Still its not showing. Also I tried deleting, cleaning app, deleting derived data.
Any idea why its happening?
Changing AppleLanguages key needs app to be restarted so new localization applied , you can try to use NSLocalizedString with tableName or change current bundle you read from , but system localization won't be changed until app restarted

Set Language in Swift 3 failed [duplicate]

This question already has answers here:
How to force NSLocalizedString to use a specific language
(28 answers)
Closed 5 years ago.
Sir.
I am trying to create an app of multi-language support. I use the abbreviations like zh-Hant, en , jp to save as user default. And change the language of the app. Taking place holder of textfield as an example, if I click the collection view item, the text of place holder of textfield will change. However , I can't do this. The simulator language is English as default
Here is my work in-progress :
Localisation File : Japan (jp)
"User Email"; = "ユーザーメール";
Set Text method
let lcode : String = self.langList[indexPath.item].code
print("You selected cell #\(indexPath.item) and code : \(lcode)")
UserDefaults.standard.setValue(lcode, forKey: "lang")
txtUsername.placeholder = "User Email".localized(lang: lcode)
String exntension
extension String {
func localized(lang:String) ->String {
if let path = Bundle.main.path(forResource: lang, ofType: "lproj") {
if let bundle = Bundle(path: path) {
return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
}
}
return "";
}
The language of the app is dependant on the device language. To test the localized string, change your device language. Otherwise, though this is not recommended, you can change your app language on runtime by adding UserDefaults.standard.set("zh", forKey: "AppleLanguages") to your ViewController. But you will have to restart the app to see the language changes.

iOS: How to retrieve locale strings for a specific locale than what the user has set in OS?

Is it possible to retrieve strings for a specific locale programmatically regardless of what locale the phone is set to? For example, users may be running the phone in English, but I want to retrieve French strings instead without changing the OS locale setting.
Note: This is not a duplicate of the above question. I do not want to override the current setting within my app, I merely want to have the ability to retrieve language values of whatever locale I wish programatically. My app contents may be displaying English text, but I want a specific component of my app to display a different language instead.
I solved this by extending String with this method. You can get localized string for any locale you have in your app this way.
extension String {
func localized(forLanguageCode lanCode: String) -> String {
guard
let bundlePath = Bundle.main.path(forResource: lanCode, ofType: "lproj"),
let bundle = Bundle(path: bundlePath)
else { return "" }
return NSLocalizedString(
self,
bundle: bundle,
value: " ",
comment: ""
)
}
}
Example (get localized string for ukrainian language when system language is english):
"settings_choose_language".localized(forLanguageCode: "uk")

Resources