Set default language with localization - ios

Is it possible to use a default language for the localization? for example if a key is not found for one language, than the system will look at it automatically in the English language? If it's not possible to do it automatically, would it be possible to do it manually? look for a key in the current language, if not found then force the system to look at it in the English language? In my current app, when a key is not set, the key name is returned.

Here is a method that do what you want (I didn't find an "official" way to do it).
func localizedString(_ key: String) -> String? {
let localeString = NSLocalizedString(key, comment: "")
// Base can be changed by en or the default language of your choice
if localeString == key,
let path = Bundle.main.path(forResource: "Base", ofType: ".lproj"),
let baseBundle = Bundle(path: path) {
return baseBundle.localizedString(forKey: key, value: nil, table: nil)
}
return nil
}

Related

Return a string if localized string not found

I would like to know how could I return a default string value if localized string of key is not found. here is my function to return the localized String.
func localizedStr(key: String) {
return NSLocalizedString(key, comment: "")
}
I would like to return default string e.g. "foo" if the key is not found in localization file.
TL;DR
Use the full
NSLocalizedString(key: "key", value:"English string", comment: "")
If key is not found in your translated file, value is returned
Long version
Don't wrap NSLocalizedString in a function - while there's less code, you're losing valuable information for the localisation process.
you won't be able to use Xcode export an Xliff file for translation - only string literal keys in NSLocalizedString are included
Use a value: parameter with the English (or your base language) string. This is used when no translation is found, and means you don't need to have a base Localizable.strings file.
The comment: appears in the xliff file, and is useful for translators. Use this to give information about the context of the string being translated.
You could give it default value like this, using NSLocalizedString(key, comment: "") would return an Empty String if the Key was not found so checking on it like this should do the trick.
func localizedStr(key: String) {
if NSLocalizedString(key, comment: "") == key {
return "foo"
}
return NSLocalizedString(key, comment: "")

How to compare Localized string with the string from the database?

I have a to compare a string with the string from the db.
var variableFromDB = "test"
if "test" == variableFromDB{
print("Success")
}
It works fine in the English Language. I don't know how to compare it in the arabic language. Is the need to check in arabic language also. Please tell me know to check it.
In general it's a bad idea for your code to make decisions based on display strings. That goes double for display strings.
If your primary audience is Arabic-speaking, you could make your development language Arabic and then localize for other languages as needed.
In any case, I would suggest using a set of fixed strings as keys, and then calling NSLocalizedString(_:tableName:bundle:value:comment:) or one of it's variants to fetch a display string. Example:
Put this code somewhere central so the keys can be shared:
let screen1Prompt = "screen1Prompt"
Then when you need a localized string for display:
let prompt = NSLocalizedString(screen1Prompt)
Where the actual prompt string might be "Please select the date for your payment." in English, Arabic, etc.
Then if you need to match something in your database, look it up using the unlocalized key, not the localized display string.
That way if you later change the display string, your code still works.
var language: String
UserDefaults.standard.set("AE", forKey: "Apple") // manually set language
UserDefaults.standard.synchronize()
self.language = UserDefaults.standard.object(forKey: "Apple")as! String
// self.language = Locale.current.languageCode // your device language
extension String {
func stringlocalized(lang:String) ->String {
let path = Bundle.main.path(forResource: lang, ofType: "lproj")
let bundle = Bundle(path: path!)
return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "")
}}
// Check You Localization string from your current language
let str = “ test”.localized(lang: self.language! )
if str ==variableFromDB
{ // Your logic here
}

Unable to use localizable strings

I am trying to follow all instructions I have found in previous questions in term of localizing the application.
I Have succeeded in localizing storybaord when strings were generated. Now I am trying to prepare .strings file in order to use them in my swift files.
what I did:
new -> file -> strings file
Create localization of at least 2 languages on the previously created .strings file
I have put values in (polish)
"HELLO_WORLD" = "Dzień dobry!";
and in (english)
"HELLO_WORLD" = "Hello world!";
I have created string extension as follows:
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
I am trying to show the value like:
`helloworldLabel.text = "HELLO_WORLD".localized
but everything I gets is the same result. In hello world label I see "HELLO_WORLD"
can anyone give me a hint what Am I doing wrong?

iOS Base localization was not used for missing key

Let's say I have this 2 strings files in my project:
Localizable.strings (Base)
"hello_key" = "Hello";
"bye_key" = "Goodbye";
and
Localizable.strings (Chinese Traditional)
"hello_key" = "您好";
And I use the following code to localize the "hello" string
NSLocalizedString("hello_key", comment: "")
It works fine for "hello_key", but if I use "bye_key" in my iPhone with phone language set to Tradition Chinese, I get "bye_key" as the localized string.
In another word, the Base localization was not used. Is it possible to show the Base English "GoodBye" in this case?
Thanks.
This is the case of unsupported phrase, because your did not translate completely for Traditional Chinese.
Apple will not fallback to the base language, but simply return the key. This is just how it behaves. I wrote more about it in my blog.
You have to write a custom NSLocalizedString like this (the example uses en as the fallback language):
public func LS(_ key: String) -> String {
let value = NSLocalizedString(key, comment: "")
if value != key || NSLocale.preferredLanguages.first == "en" {
return value
}
// Fall back to en
guard
let path = Bundle.main.path(forResource: "en", ofType: "lproj"),
let bundle = Bundle(path: path)
else { return value }
return NSLocalizedString(key, bundle: bundle, comment: "")
}

How to get detailed language of device in swift

I have a database on the server that contains all the languages keywords that I use inside my applications and these languages could be changed any time.
In the language table of database there is column for Language (id , key, value, lang).
In the android application I read the language from device and it returns for example en-GB or en-US.
But in the iOS application I can't get the language like the above example , It always returns just the language (en , es, fr).
So I can't query to database to get the language specified keywords on the iOS application. Because the languages on the database is en-GB, en-US style.
var langId: String? = NSLocale.preferredLanguages().first as? String
How can I get the language with more details ?
Start with the currentLocale() and ask questions about it. For example:
let lang = NSLocale.currentLocale().localeIdentifier
Or, at a finer level of granularity:
let langId = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode) as! String
let countryId = NSLocale.currentLocale().objectForKey(NSLocaleCountryCode) as! String
let language = "\(langId)-\(countryId)" // en-US on my machine
Swift 3 does not have an NSLocaleCountryCode, this is replaced by regionCode
https://developer.apple.com/reference/foundation/nslocale.key/1417845-countrycode
solution in Swift 5:
let langCode = Locale.current.languageCode ?? ""
let regionCode = Locale.current.regionCode ?? ""
let language = "\(langCode)-\(regionCode)"
Another solution is NSLocale.current.identifier
This will return e.g. en_us
You could replace _ for -. it will look like this: NSLocale.current.identifier.replacingOccurrences(of: "_", with: "-")
No need an extra effort, just use the following as per your requirement.
Locale.current.identifier //en_US
Locale.current.collatorIdentifier //en-US
For Swift 4 use instead:
NSLocale.current.identifier //Output: en-US, pt-BR
Swift 5
Locale.currentLanguage.rawValue
just use this code line can solve:
let identifier = Locale.current.identifier

Resources