localizedStringForKey:value:table: with CFBundleDevelopmentRegion - ios

I have the following:
And the CFBundleDevelopmentRegion is set as "en" in the Info.plist:
The default language is english and has all the strings. The swedish and french version are not complete and I want to fallback in english when a string is not localized in fr or sv.
Here's how I translate:
translatedContent = [[NSBundle mainBundle] localizedStringForKey:translationKey
value:nil
table:#"Localizable"];
When the device is in english, everything is fine.
However, when the device is in swedish or french, it works but the translation does not fallback to english if the key is not present in the sv/fr file. Instead, it fallbacks to the translation key.
I can't figure out what is wrong. Any thoughts?

Related

Is there a way to set English as a default language

I localized my app for 2 languages (EN, FR). When iPhone language set to English, app shows up in English. When iPhone language set to French, app shows up in French. But when iphone language set to another language lets say Spanish app shows up in French not in English.
I set "Localization native development region" to "en" or "United States" in my Info.plist file but didn't help.
Main.storyboard (Base) also in English.
Solution:
One way to do it is to get the English string from en.lproj if the preferred language does not match en or fr.
This is how you get the preferred language:
let preferredLanguage = Locale.preferredLanguages[0]
This is how you get the English string using your localized key:
if let enPath = Bundle.main.path(forResource: "en", ofType: "lproj") {
let enBundle = Bundle(path: enPath)
enBundle?.localizedString(forKey: "your_key_here", value: nil, table: nil)
}
Explanation of your problem:
In iOS native Settings App -> General -> Language & Region, there is a Preferred Language Order list.
Apps and websites will use the first language in this list that they
support.
For example:
Set "French" as your iPhone Language.
Open the App and everything is localized in French because your app does support French.
Set "Spanish" as your iPhone Language.
Open the App and everything is localized in French because your app does not support Spanish and it'll fall through your next preferred language which is French in this case.
Just set developer language to English
YOURPROJECT.xcodeproj -> show package content -> Editing the .pbxproj file directly using a text editor - look out for the developmentRegion property
And change the Localizations native development region property in the Info.plist accordingly en Or bellow image
once your result like this then you setup successfully :
]1

Why [NSBundle localizedStringForKey] does not return the iPhone language localised string?

Why localizedStringForKey returns the localization of the development language first instead of the language of the iPhone? The "Bundle Search Pattern" in the documentation says:
If a .lproj folder exists for the preferred language, that localization is used. Otherwise, the bundle searches for a .lproj folder matching the next preferred language, and so on, until one is found. If there is no localization for a preferred language, the bundle chooses the development language localization.
Then the bundle searches for the resource in the following order [...]
But it does not make sense to me.
The test iPhone is in Chinese, french keyboard, the bundle contains 32 languages and the development language localization in English. I don't understand why it makes sense to return the English localization first. Why not is the Chinese one as this the iPhone language?
NSArray* arr = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
// ( zh-Hant-FR, en-FR, fr-FR )
NSArray* localizations = [bundle localizations];
// ar,bg,ca,cs,da,de,el,en,es,fr,he,hu,id,it,ja,ko,ms,nb,nl,nn,pl,pt,pt_BR,ro,ru,sv,th,tr,uk,vi,zh-Hans,zh-Hant
NSArray* preferredLocalizations = [bundle localizations];
// same output
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
NSString* str = [bundle localizedStringForKey:#"hello" value:#"" table:#"mytable"];
// hello
How should I fix this? I would like localizedStringForKeyto always return the iPhone language localization whatever the development language.
Use this
NSLocalizedStringWithDefaultValue("requiredTranslationKey", #"StringFileName", [NSBundle mainBundle], #"", #"");

iOS wrong localization

I have an iOS application that is localized in multiple languages. I have Localizable.strings files for English, Dutch and Dutch (Belgium). The problem is that when Dutch is set as the device language and Belgium as the country, the Dutch strings are used and NOT the Dutch-Belgium strings.
I've added some logging to make sure that the correct language is set on the device, and it appears to be correct:
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [locale displayNameForKey:NSLocaleIdentifier
value:[locale localeIdentifier]];
NSLog(#"language %#", language);
This prints out
2015-04-09 11:49:26.227 MyTestApp[222:7459] language Nederlands (Belgiƫ)
But if I try to get a string using NSLocalizedString I get the Dutch resource, not the Dutch Belgium one.
I've tested this on an iPhone 5s running 8.1 and on several 7.1/8.1 simulators and I can't get it to work. The interesting thing is that if I forcefully set the language to Dutch (Belgium) in XCode under Edit Scheme -> Application Language, the correct language is used.
It turns out that the problem is that Xcode creates resource folders for each language with a hyphen separating the language and region, e.g. nl-BE.proj. However, the locale code uses an underscore, e.g. nl_BE, so the region is never matched. This appears to be an XCode bug.
The solution is to change the locale so that it includes a hyphen as discussed here https://stackoverflow.com/a/14357315/416214

localizedStringForKey:value:table ignores Base localization

My application need to be localised in 2 languages: German and English. German should be Base language. It means that app should always localize to German except the language on device is english (in this case it should be on english)
I have custom *.string files for localisation and use localizedStringForKey:value:table to localise strings.
When I have only base localisation everything works fine. But in case if I add english localisation, in some reason localizedStringForKey:value:table just ignore Base localisation and always use English (for all languages)
Here how it looks like after I've added english:
and here is how I localise strings:
[[NSBundle mainBundle] localizedStringForKey:#"key" value:#"" table:#"Shared"]
I'm testing on simulator and here is my language screen:
Does anybody know what could be a problem? Thanks in advance!
As I mentioned in the comments, you need to set the Localization native development region (CFBundleDevelopmentRegion) in the Info.plist to your language code. Xcode seems to set it to a en_GB or de_DE style region code, setting it to de (no region) will fix it. Note that by default it is en, but selecting United Kingdom or Germany will change it to use the longer codes.
I have another solution, I think it works for you:
NSString* NSCustomLocalizedString( NSString *key , NSString *comment)
{
NSString *rs = nil;
if( [[NSUserDefaults standardUserDefaults] integerForKey:KEY_LANGUAGE ] == e_language_japanese)
{
rs = NSLocalizedStringFromTable(key,#"Localizable.strings-ja",nil);
}
else
{
rs = NSLocalizedStringFromTable(key,#"Localizable.strings-en",nil);
}
return rs;
}

Finding the current localization of iOS app in code

Connected issue: Non-English default language for iOS App?
I am wondering how to check the current localization of my app in code.
For example:
I want to check if the app is running with German localization (.strings, storyboard)
This line of code:
[[[NSLocale preferredLanguages] objectAtIndex:0] isEqualToString:#"de"]
doesn't provide the correct answer. Because if a user's language list in device settings looks like this for example (french, german, english) and we have only localization for english and german, application is launched in german but the above condition isn't fulfilled.
My naive solution would be to create a localized string "LanguageCode" which is set to "de" in the german string file and to "en" in the english string file
e.g.:
if ([NSLocalizedString(#"LanguageCode", #"en, de etc.") isEqualToString:#"de"]) {
// german
}
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
This will return a two letter code for the currently selected language. "en" for English, "es" for Spanish, "de" for German, etc. For more examples, please see this Wikipedia entry (in particular, the 639-1 column):
Check the first entry of Bundle's preferredLocalizations property, which is:
an array of NSString objects containing language IDs for localizations
in the bundle. The strings are ordered according to the user's
language preferences and available localizations.
For example, if you're checking to see if your German localization are being used:
if Bundle.main.preferredLocalizations.first == "de" {
// Is using German
}

Resources