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: "")
}
Related
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: "")
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
}
I have user localizable strings for the strings used in storyboard or source files which are fixed. These are defined in files like Localizable.string (Spanish), Localizable.string (German) etc. But I have a requirement where these strings can keep changing. These strings are received as a response to REST API call. My question is how can I use it.
Current code is let text = NSLocalizedString("Some string", comment: "")
Where NSLocalizedString looks for Localizable.string file. How can I make NSLocalizedString look for localized words from my custom dictionary/Json?
Try this
First you need to copy that files in document directory .
Get Localised Label
let localisedString = self.getLocalizatioString(key: "your key", stringFileName: "test.strings") //
Function
func getLocalizatioString(key : String?, stringFileName : String ) -> String {
let doumentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let destinationPath = doumentDirectoryPath.appendingPathComponent(stringFileName)
let dict = NSDictionary.init(contentsOfFile: destinationPath)
return (dict?.object(forKey: key!) as? String)!
}
Output
In String file
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
}
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?