Swift localization with possessive - ios

I'm dabbling with localization in Swift. It's been pretty straightforward until I have to deal with possessive.
Say I have these phrases in English:
Carol's car is red.
Kris' car is red.
In French, they would be
La voiture de Carol est rouge
La voiture de Kris est rouge
How would I set up my Localizable.strings (French) file? I'd imagine it's something like:
"key" = "La voiture de %# est rouge";
But this doesn't really work.

Yes, you can replace text with you required value. I have just using your flow of questions, so answer is same it is.
First create your localized string as follow:
"key" = "La voiture de #name# est rouge";
Then, when you required your string. i.e
let strFrench = Localizable.strings(French)
Localizable.strings(French), this is you are assuming, so I have wrote this.
Now replace name with your dynamic value as follow:
let str = strFrench.replacingOccurrences(of: “#name#”, with: “YourString”)
I hope this will work for you. Sorry for my bad English.

Try this method..
First you declare language bundle globally like as below
var languageBundle:Bundle?
then you set path for your language ,
if let path = Bundle.main.path(forResource: "Fr", ofType: "lproj") {
languageBundle = Bundle(path: path)
} else {
languageBundle = Bundle(path: Bundle.main.path(forResource: "Base", ofType: "lproj")!)
}
then you assign the key name to your label
labelTerms.text = ((languageBundle?.localizedString(forKey: "labelAcceptTerms", value: "", table: nil) as String!))
Thats all!!
Before you proceed please confirm you followed below steps for creating localized string file
Select project —> Select Use base Internationalization — > add language —> Goto storyboard and add select the checkbox (New languages added) — > add a string file localized.string —> add list of strings in that --> Use the key name .localizedString(forKey:"addyourkeyname"

Related

How can I localise my multiple string in swift?

When I do as below, I can write all string expressions in different languages. But it doesn't happen when I make a multi line String. Please help me on how to Integrate this?
Modal
Unit(unit: "Unit 1".localized(),
category: [Category(category: "Personal Pronouns".localized()])
controller
extension String {
func localized() -> String {
return NSLocalizedString(self,
tableName: "Localizable",
bundle: .main,
value: self,
comment: self)
}
}
localizable.string
"Unit 1" = "Unité 1";
"Personal Pronouns" = "Pronoms personnel";
The multi line string I want to do will be like this but how ?
let text = """
We want to change the World
but not everywhere or everything
only on people
"""
https://github.com/ysrtirak/Make-localise
here there is my example
I could not translate the text in """ """
I haven't tried it, but according to this SO answer you can put multi-line strings directly into your localizable.strings file:
localizable.strings:
"multiLine" = "We want to change the World
but not everywhere or everything
only on people";
And in your swift code:
print("multiLine".localized())
I just tried a test application, and the following localizable.strings file worked perfectly:
/*
Localizable.strings
MultiLine
Created by Duncan Champney on 8/13/21.
*/
"foo" = "This
is
a
multi-line
string";
With that localizable.strings file, this code:
print(NSLocalizedString("foo", value: "foo", comment: "comment"))
prints the output:
This
is
a
multi-line
string
Just as you would expect it to.
Edit:
Try downloading this sample app from Github. It is a working example of using multi-line strings in a localizable.strings file.
Edit #2:
You have an extra newline at the beginning and end of the English in your French localizable.strings. Change it as follows:
/*
Localizable.strings
Make localise
Created by Yasir Tırak on 15.08.2021.
*/
"I know how to localise that . thats not problem" = "Je sais comment localiser ça. ce n'est pas un problème";
"This is my text
But i cant localise it
hey
how are you" = "C'est mon texte
Mais je ne peux pas le localiser
Hé
Comment ça va";
That works.
To figure out what was going on, I broke your code into steps and logged the results:
let text = """
This is my text
But i cant localise it
hey
how are you
"""
print("text = '\(text)'")
let localizedText = text.localized()
textLabel.text = localizedText
That outputs:
text = 'This is my text
But i cant localise it
hey
how are you'
Note how there are no newlines before the first single quote and none after the last single quote.

Set default language with localization

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
}

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
}

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