I want to get current selected iphone language. If using "NSLocale" it returns always the same language. It seems that this is not the one you choose inside iphone settings.
NSLocale * locale = [NSLocale currentLocale];
NSString * localLanguage = [locale objectForKey:NSLocaleLanguageCode];
NSLog (#"Language : %#", localLanguage); // Returns always : "en_US"
How to obtain the current language?
The answer is to check the preferred language :
NSString *preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
This question is old, but the reason is new since upgrading to Xcode 6.1
Due to a bug, the iOS8 simulator's [NSLocale currentLocale] always returns "en_US". It is alright on the device though.
Hence, I recommend doing a test on a real device before bashing your head against a wall in frustration.
Sources: https://stackoverflow.com/a/26510914/3099609
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-DontLinkElementID_23
Locales encapsulate information about linguistic, cultural, and technological conventions and standards.
Your code returns the "Region Format" information, if set "China", it will return "zh".
Settings | General | International | Region Format
See “NSLocale Class Reference” for more information.
To add to what SteamTrout suggested:
To get your language to respond to changes in iPhone settings you're going to want to use autoupdatingCurrentLocale:
https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSLocale_Class/Reference/Reference.html#//apple_ref/occ/clm/NSLocale/autoupdatingCurrentLocale
If you read closely in the currentLocale reference you'll see that this value will not update from the settings panel:
https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSLocale_Class/Reference/Reference.html#//apple_ref/occ/clm/NSLocale/currentLocale
Try [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleLanguageCode]
Related
Here is how I am localising days:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSString *dayFormat = [NSDateFormatter dateFormatFromTemplate:#"EEEE" options:0 locale:[NSLocale currentLocale]];
[dateFormatter setDateFormat:dayFormat];
[dateFormatter setLocale:[NSLocale currentLocale]];
NSString *day = [dateFormatter stringFromDate:date];
And yet it seems to be returning English days of the week (Monday, Tuesday etc) rather than the device language (which has been set to German in the simulator).
Any idea where I'm going wrong?
Update after doing some research on device I've realised that its actually the region setting, not the language setting which changes the date language. Odd, but I guess its done for a reason.
Thanks
The language of the date is set by the region not the language. This has to be a bug. If I'm in Germany, but an English speaker I don't want to have my dates in German, surely?
Anyway, this is why. You have to change language and region.
I've had the same issue. It wouldn't work on the simulator, but it would on a device. Can you try it ? I did not however solve it, I did not even look more into it as it was working perfectly on the device, which is truly the main target of your app.
Edit:
This comes from Apple's doc:
currentLocale
Returns the logical locale for the current user.
+ (id)currentLocale
Return Value
The logical locale for the current user. The locale is formed from the settings for the current user’s chosen system locale overlaid with any custom settings the user has specified in System Preferences.
Discussion
Settings you get from this locale do not change as a user’s
Preferences are changed so that your operations are consistent.
Typically you perform some operations on the returned object and then
allow it to be disposed of. Moreover, since the returned object may be
cached, you do not need to hold on to it indefinitely. Contrast with
autoupdatingCurrentLocale.
Maybe you can try using:
preferredLanguages
Returns the user's language preference order as an array of strings.
+ (NSArray *)preferredLanguages
Return Value
The user's language preference order as an array of NSString objects, each of which is a canonicalized IETF BCP 47 language identifier.
I'm using a webservice which provides me a list of countries to choose from as 2 letters ('us' for USA, 'es' for Spain etc.).
I need to present it to the user and send back the selection.
Is there an API on iOS to convert the country code to a country name - based on the current language? I know I can have a static mapping of codes to countries, but I would like to support other languages than English.
For example, I would like to display "Spain" for 'es' when using english locale and "Espanya" when using spanish locale.
I used this, maybe it suits your needs too:
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
NSString *countryCode = [locale objectForKey: NSLocaleCountryCode];
NSString *countryName = [locale displayNameForKey: NSLocaleCountryCode value: countryCode];
[locale release];
I've found this one, but I suggest you to build your own solution. Free APIs give you limits that maybe limit your app usage Link
OK, apparently it's easier than I though: I'm posting the answer if anyone else will have the same problem:
NSString* name=[[NSLocale currentLocale] displayNameForKey:NSLocaleCountryCode value:#"ca"];
That's it :)
I want to be able to make the app change depending on the users location. Im using the code below:
NSLocale *locale = [NSLocale autoupdatingCurrentLocale];
NSString *countryCode = [locale objectForKey: NSLocaleCountryCode];
NSString *countryName = [locale displayNameForKey: NSLocaleCountryCode value: countryCode];
NSLog(#"countryName %#", countryName);
which works great, but I want to know how the countryName's will be displayed, so I can set up switch case's, which is hard if you dont know how exactly each country is spelt: USA, United States, United States of America, etc. Is there a list of countryCode from Apple, I cant find one.
Also is there a way to make sure the result is in English?
Apple uses the ISO-3166 standard.
"ISO standard ISO-3166" is accurate in most cases, but try selecting "Europe" as a region in iOS settings. You will get a return value of "150". Why "150"? Seems like a region code from here: http://en.wikipedia.org/wiki/UN_M.49. Or from here: http://site.icu-project.org/design/t/territory-region-apis
NSLocale gets its data from CFLocale which in turn gets its data from the
ICU - International Components for Unicode (Apple keep copies here). The file /icuSources/common/uloc.cpp contains almost all the information we usually see returned.
However, /cldrFiles/supplementalData.xml may be the primary source. This file comes from the CLDR - Unicode Common Locale Data Repository.
How can I get the current ISO language code in IOS?
[[NSLocale currentLocale] localeIdentifier] will give you a string that's closer to what you are looking for. For my device here in the US, I get "en_US".
If you want a more standard looking "en-US", you can take use [[[NSLocale currentLocale] localeIdentifier] stringByReplacingOccurrencesOfString:#"_" withString:#"-"] instead.
If you just want the language code, you can pass the output of [[NSLocale currentLocale] localeIdentifier] to [NSLocale componentsFromLocaleIdentifier:] which will give you an NSDictionary back. One of the keys in the dictionary will be NSLocaleLanguageCode which will have a NSString object with just the language code.
NSString *isoCode = [[NSLocale preferredLanguages] objectAtIndex:0];
This will return a 2 letter iso code for the selected language on the device. "en" for english, "de" for german, and so on.
I hope that helps!
I want to localize strings in my iphone app for en_GB and other 'en' sub-languages, but XCode and the iphone refuse to let this happen. I have created a localization of "Localizable.strings" for en_GB and en_US (I tried both hyphens and underscores) for testing purposes, but they just aren't recognized. The only language code that works is simply "en" (displayed as "English" in XCode).
I can't believe this isn't possible, so what am I doing wrong? I'm also hoping to get the typical 'cascading' behaviour where if a string isn't found in the sub-language e.g. "en_GB" then it should be taken from "en" if possible. Help?
When you choose 'English' from the list of languages on the iPhone preferences, that actually means the 'en_US' language.
So until apple update their software with additional sublanguages like "English (British)" etc. we are left with going by the locale region setting, and loading strings manually from another string table.
However, the language and regional locale are separated for a reason: a Spanish user in the UK may want dates/times formatted according to the local customs, but program strings in their native tongue. It would be incorrect to detect the regional locale (UK) and therefore display UK strings.
So basically there is no way to do this currently.
What you're doing should work according to the docs. But it appears that the iPhoneOS implementation is at odds with the documentation. According to Radar 6158876, there's no support for en_GB language, only locale (date formats and the like).
I found the same problem.
BTW, if you look at the iPhone Settings -> General -> International menu, it makes the distinction between language and region quite clear:
Languages:
-English
Region Format:
-United States
-United Kingdom
The localization framework only appears to pay attention to the language, not the region.
I'm tempted to raise an enhancement request for this with Apple, as IMO it is reasonable that a user might want to use British English (for the text) whilst being in the United States (where, say, phone numbers should be in US format).
This can actually be done - check my solution here - iPhone App Localization - English problems?
Create a separate string resource, say UKLocalization.strings, and create localizations for each of your supported languages. For all localizations other than en this file is empty. For en, it contains only the strings that have unique en_GB spelling.
Next, you create a replacement for NSLocalizationString that will first check the UKLocalization table before falling back to the standard localization table.
e.g.:
static NSString* _locTable = nil;
void RTLocalizationInit()
{
_locTable = nil;
NSString* country = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
if ([country isEqual:#"GB"])
{
_locTable = #"UKLocalization";
}
}
NSString* RTLocalizedString(NSString* key, NSString* ignored)
{
NSString* value = nil;
value = [[NSBundle mainBundle] localizedStringForKey:key value:nil table: _locTable];
if (value == key)
{
value = NSLocalizedString(key, #"");
}
return value;
}
I’m not sure in which version of iOS it was introduced, but iOS 7 definitely has a ‘British English’ language preference that will pick up resources from the en_GB.lproj directory. The various hacks floating around the web shouldn’t be necessary unless you’re after a more specialised* dialect.
*see what I did there ;)