Translate language code with Xcode 6.1 using NSLocale - ios

Since the last update, I can't translate the language code (en, fr, etc...) into their respective names (English, French, etc...).
It works on a real device, but not in the emulator. It was working using former versions of Xcode. I'm aware that it's written in the release notes that [NSLocale currentLocale] may return en_US in some situations, but that doesn't explain why they are no more "translated". I use this code:
NSString* lang = #"en";
NSLog(#"%#",
[[NSLocale currentLocale]
displayNameForKey:NSLocaleIdentifier
value:lang]
);
which displays (null), instead of English.
The problem is that my app is crashing at some places because of that so I would like to know if there's a workaround.
The weird thing is that the following example, given by Apple, works really well.
NSLocale *frLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"fr_FR"];
NSString *displayNameString = [frLocale displayNameForKey:NSLocaleIdentifier value:#"fr_FR"];
NSLog(#"displayNameString fr_FR: %#", displayNameString);
displayNameString = [frLocale displayNameForKey:NSLocaleIdentifier value:#"en_US"];
NSLog(#"displayNameString en_US: %#", displayNameString);

From Xcode release note
In some situations, [NSLocale currentLocale] may return en_US instead
of the chosen locale in the iOS 8.1 simulator. (18512161)
+ (NSLocale *)autoupdatingCurrentLocale NS_AVAILABLE(10_5, 2_0); // generally you should use this method
+ (NSLocale *)currentLocale; // an object representing the user's current locale
A workaround is to use the first one. Using objectForKey on currentLocal instance works.
NSString* lang = #"en_US";
NSLocale *currentLocal = [NSLocale autoupdatingCurrentLocale];
//get the localeIdentifier and create a new NSLocale.
id localIdentifier = [currentLocal objectForKey:NSLocaleIdentifier];
NSLocale *theLocal = [NSLocale localeWithLocaleIdentifier:localIdentifier];
NSLog(#"%#",[theLocal displayNameForKey:NSLocaleIdentifier
value:lang]
);

This is a known Apple issue for iOS 8.1 simulator only - not reproducible on 8.1 devices. See below issue description from Xcode 6.1 release notes:
Localization and Keyboard settings (including 3rd party keyboards) are
not correctly honored by Safari, Maps, and developer apps in the iOS
8.1 Simulator. [NSLocale currentLocale] returns en_US and only the English and Emoji keyboards are available. (18418630, 18512161).
See Xcode 6.1 Release Notes for more details.

Related

ios sdk maneuver instructionsForLanguage:language unitSystem array empty

I am working on developing the cordova HERE map plugin to get route calculation data in app. I am working on adding the functionality for ios.
I want to get a maneuver instructions for the route, following is my code to get maneuver instructions for the calculated route.
NSString * language = [[NSLocale preferredLanguages] firstObject]; // getting lang code en
NSArray* inst= [route instructionsForLanguage:language unitSystem:NMARouteInstructionsUnitSystemMetric];
But I don't know why it is returning empty array. Please help it anyone knows how to get maneuver instructions.
That happening because NSLocale preferredLanguages can give you language code instead of language and country code, for example
[NSLocale preferredLanguages] // -> tr
According to HERE maps documentation function expect language code, like en-US
language should be a valid code according to the IETF BCP-47 standard (see http://tools.ietf.org/html/bcp47 ).
So to make it easier for you, to need to get language code instead.
NSLocale *locale = [NSLocale currentLocale];
NSString *language = [NSString stringWithFormat: "%#-%#", [locale languageCode], [locale countryCode]]; // -> tr-TR

Which NSLocale to use with uppercaseStringWithLocale:?

When I have an UI string with capital letters, i'm used to define them in lowercase as for all the others, and then to use uppercaseStringWithLocale:[NSLocale currentLocale].
But recently I happened to notice that the [NSLocale currentLocale] may not be the one used in your app. For example if your device is in Turkish but your app only support english, the currentLocale would be a Turkish locale while your app is localized in english.
With those settings, a direct effect of using [NSLocale currentLocale] is that my uppercaseString will be "İ LİKE İOS" instead of "I LIKE IOS".
So far, the only workaround I see is to create a category of NSLocale to add a +(NSLocale*) applicationLocale; and use it in all uppercaseStringWithLocale:.
+ (NSLocale*) applicationLocale
{
NSMutableDictionary<NSString*,NSString*>* localeComponents = [[NSLocale componentsFromLocaleIdentifier:[NSLocale currentLocale].localeIdentifier] mutableCopy];
localeComponents[NSLocaleLanguageCode] = NSBundle.mainBundle.preferredLocalizations.firstObject;
return [NSLocale localeWithLocaleIdentifier:[NSLocale localeIdentifierFromComponents:localeComponents]];
}
My question is simple: am I doing this the right way or did I miss something? I indeed wonder why Apple links to currentLocale while it won't work as expected in a lot of cases.
The most robust way to get the application locale is to edit your Localizable.strings files. In the English localization file add an entry
"lang"="en";
in the German localization file add an entry
"lang"="de";
in the French localization file add an entry
"lang"="fr";
and so on... You can get the localization code with NSLocalizedString(#"lang").

iOS 9 beta Language ID syntax change

I'm quite confusing, why in iOS 9 beta the return value of language code is different from iOS 8.4?
Function:
NSUserDefaults.standardUserDefaults().objectForKey("AppleLanguages")
Just set Language to "Simple Chinese" and Region to "China".
In iOS 8.4, return "zh-Hanz" but in iOS 9 beta 4 return "zh-Hanz-CN".
The Language ID syntax is much more like
"[language designator]-[script designator]-[region designator]".
Is different with apple document:
Is it a new rule in iOS 9? Can someone help me to confirm this.
Thank you for your help.
Yes, I noticed it too while using
[NSLocale preferredLanguages]
In iOS 9 beta it returned zh-Hans-US ( with region set to US and language to Chinese Simplified ) whereas in iOS 8.4 it used to return zh-Hans only.
So meanwhile I have been using
[[NSBundle mainBundle] preferredLocalizations]
This returns the current localization ( zh-hans ) which is without the region post-fix ( -US )
To confirm, iOS 9 adds the region post-fix ( like -US or -CN ) to all of the languages.
You should use componentsFromLocaleIdentifiert to split the locale identifier and find the language code. Like here:
+ (NSString*)currentLanguage
{
NSLocale* locale = [NSLocale currentLocale];
NSString* identifier = locale.localeIdentifier;
NSDictionary* components = [NSLocale componentsFromLocaleIdentifier:identifier];
NSLog(#"components:\n%#", components);
return [components valueForKey:NSLocaleLanguageCode];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *allLanguage = [defaults objectForKey:#"AppleLanguages"];
NSString *currentLanguage = [allLanguage objectAtIndex:0];
NSLog(#"The current language is : %#", currentLanguage);
iOS 9 Before:returns:language ID.for example:"zh-Hans"
iOS 9:returns:Language ID + region ID.for example:"zh-Hans-US"
Notice:
1.Don't use the following method to check the current language.
if ([currentLanguage isEqualToString:#"zh-Hans"])
you can use the following method instead:
if ([currentLanguage hasPrefix:#"zh-Hans"])
Also:If you care about Chinese,you must pay attention to these:
Simplified Chinese:zh-Hans
Traditional Chinese:zh-Hant
Hong Kong Chinese:zh-HK
Macao Chinese:zh-MO
Taiwan Chinese:zh-TW
Singapore Chinese:zh-SG
Notice:In some case,we have different result,especially when you deal with Chinese.It's a little strange.For example:
My mobile phone is:China Mainland/China Telecom/A1533/16GB
version.When I choose the language as Taiwan,the region is
China,HongKong or Taiwan,the result is "zh-TW",and when you set the
region as Not Chinese Region,the language will change to the
traditional Chinese.
So please pay more attention to the language especially when you deal with the language Chinese!
You can also check the iOS 9 adaption details here:https://github.com/ChenYilong/iOS9AdaptationTips

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

Facebook in-app showing up in different language

I have a very bizarre issue with the facebook-ios-sdk. Client is complaining about the in-app dialogs showing up in Spanish, when neither their Facebook nor phone is set for spanish. This is happening across multiple devices and multiple users/accounts.
The Facebook SDK should be pulling the user's language/locale preferences from NSLocale, correct? Is there a way to set or test this? Is there some way the language is being set in the HTTP Header Requests for the in-app dialog incorrectly?
(using SSO if it makes a difference)
Thanks,
This is apparently a Facebook-level issue. You can track the status here:
http://developers.facebook.com/bugs/407246299295529?browse=search_4fa410ea79db26337556383
"On initial login using Facebook, the dialog asking the user to authorize this application is displayed in seemingly random languages.. Only Happens when user is connected over Wifi."
You can check the country code:
NSLocale *locale = [NSLocale currentLocale];
NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
NSString *language;
if ([[NSLocale preferredLanguages] count] > 0)
{
language = [[NSLocale preferredLanguages] objectAtIndex:0];
}
else
{
language = [locale objectForKey:NSLocaleLanguageCode];
}

Resources