How can I get which language an app is running on? And I don't mean the preference set into settings!
Let me explain it further...
I localised my app with three languages: English, Italian and Spanish. If the iPhone is set on Italian or Spanish, the app will use those two... it falls back to English otherwise.
For example: a French user gets the English version... so even if French is the language set, my app automatically use English. Now... how can I return this "value" in my code?
Thanks!
You can get the user's preferred language using:
NSString *languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
The [NSLocale preferredLanguages] array actually contains all the user's preferred languages in descending order, so you can just loop through it until you find one that your app supports.
Dont really undertstand what this And I don't mean the preference set into settings! means?
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defaults objectForKey:#"AppleLanguages"];
NSString *currentLanguage = [languages objectAtIndex:0];
You just need to get the current language of the device (as explained above by other users) and compare it with the languages supported by your app, something like:
currentLangue = //get current language with code in other answers
languageToUse = ""
for each language in languagesSupportedbyMyApp
if currentLanguage == language
languagetoUse = language
//if no language is found then set it to "en"
if languageToUse == ""
languageToUse = "en"
regards,
Fernando
Related
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 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]
I have an app that I am translating to a bunch of different languages. The problem is that the app will have a few different values in Australia than will in New Zealand, which are both English speaking countries.
I have created an en_AU and an en_NZ language file, but they're both using the standard English file. I deleted the English language file, but it continues to happen...
Any ideas on how I can get this to work?
Thank you,
--d
iPhone localisations (or is that localizations?) do not take any notice of the Region the user sets (ie, UK, Aus, NZ). There is only one "English" language translation available by default. However, you can hack around with things to force it to use a different translation setting - I've just done this for choosing between "English" (US) and "en_GB" (British english).
In your main.m file, alter it so it looks something like below (put in your own tests for NZ or AU)
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Set up the locale jiggery pokery
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *locale = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];
if ([language isEqualToString:#"en"] && [locale isEqualToString:#"GB"]) {
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en_GB", #"en", nil] forKey:#"AppleLanguages"];
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
This pops the users language (eg "en") into the language NSString, and the users locale (eg, NZ, GB, AU) into the locale NSString. If they (in my case) match en and GB, then I set the users default language preference settings to be "en_GB", then "en".
Then, in your application delegates application:didFinishLaunchingWithOptions method you want to remove that NSUserDefaults setting you just set with the code
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"AppleLanguages"];
It's safe to remove at this point because all the bundle initialisation has been completed. Your app should now be using a Localization.strings file within the en_GB.lproj directory.
It's a bit of a horrible, hacky solution, but it works for me.
I've come up with what I think is a slightly improved version of rickerbh's accepted answer. The first thing to realize is that user defaults are organized into domains, and the #"AppleLanguages" key comes not from the app's domain, but from some domain higher up the hierarchy of domains. This means it is completely safe to remove it from user defaults:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"AppleLanguages"];
After calling this code, you'll notice that calling [defaults objectForKey:#"AppleLanguages"] still returns a value. So, rather than deleting #"AppleLanguages" at some point later, which could be problematic depending upon the complexity of your app, you want to do the opposite: delete #"AppleLanguages" immediately. Essentially, this resets it back to its default value and captures any changes to it the system has made, if, for instance, the user has changed her preferred language.
Here's what I do:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"AppleLanguages"];
NSMutableArray *appleLanguages = [[defaults objectForKey:#"AppleLanguages"] mutableCopy];
NSString *region = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
NSArray *languages = [appleLanguages filteredArrayUsingPredicateFormat:#"not (self contains '-')"];
for (NSString *language in languages) {
NSString *languageAndRegion = [NSString stringWithFormat:#"%#-%#", language, region];
[appleLanguages removeObject:languageAndRegion];
}
for (NSString *language in languages) {
NSString *languageAndRegion = [NSString stringWithFormat:#"%#-%#", language, region];
NSInteger index = [appleLanguages indexOfObject:language];
[appleLanguages insertObject:languageAndRegion atIndex:index];
}
[defaults setObject:appleLanguages forKey:#"AppleLanguages"];
(Note that filteredArrayUsingPredicateFormat: is an extension method I wrote. It's not rocket science to figure out what it does or how it works.)
This creates localizations for every language in the list combined with the user's region. E.g., if the original list was es en en-GB and the user's region is AU, we'll get es-AU es en-AU en en-GB. Note that es-AU doesn't exist, but it makes no difference. Since the app finds no associated localizations or resources, it just ignores it.
Apple documents this missing iOS feature here.
Important: In iOS, the bundle
interfaces do not take dialect or
script information into account when
looking for localized resources; only
the language designator code is
considered. Therefore if your project
includes language-specific project
directories with both a language and
region designator, those directories
are ignored. The bundle interfaces in
Mac OS X do support region designators
in language-specific project
directories.
I had the same problems with German and think I found the "right" solution. The mistake was, that originally my base language was only "German (de)", when adding "German/Austria (de_AT)" localizations, the files were ignored. When changing the base language to "German/Germany (de_DE)" the austrian translations were not ignored.
Worth noting here that XCode is very misleading - you can go to Project (not Target), Info, Localizations, press the + button that appears under the list of languages, then scroll down to the bottom of the list of languages that appear in the popup until you get to "Other" (with right arrow next to it), this will open a nice big list which includes regional variants for languages. However, these regional variants do not work on the iPhone - you don't get anything (as documented by Apple and referenced in another answer that appears here). Evidently one of the code-based solutions listed above is necessary.
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 ;)
I have an iPhone application which has a button to change display language in run time. I have looked at NSLocalizedString() which will return the appropriate strings according to system preference. What are my options rather than hard coding all the display strings and return according to user language selection in run time? Any pointers will be much appreciated.
Based on the post by the user "object2.0", I've put together some sample code you can use in your application to change the UI language on the fly.
The main localization class that does the hard work:
-(NSString *) localized:(NSString *) key
{
GameInfo *gameInfo = [GameInfo sharedInstance];
// langCode should be set as a global variable somewhere
NSString *path = [[NSBundle mainBundle] pathForResource:langCode ofType:#"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
return [languageBundle localizedStringForKey:key value:#"" table:nil];
}
Assuming you have this function in a global class called utils, call this function with the following code (for example to output the word "Settings".
NSLog( [utils localized:#"Settings"] );
To change the language:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:langCode, nil] forKey:#"AppleLanguages"];
Use to set language order by force
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en",#"de",..., nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
then use
NSLocalizedString();
to show localized string...
The trick to use specific language by selecting it from the app is to force the NSLocalizedString to use specific bundle depending on the selected language ,
here is the post i have written for this http://learning-ios.blogspot.com/2011/04/advance-localization-in-ios-apps.html
and here is the code of one sample app https://github.com/object2dot0/Advance-Localization-in-ios-apps
The correct "User experience" is for the user to select their language via the system preference panel; not your app (or your app's settings panel, etc.). There is no way to override this per-app and you wouldn't want any app changing the system wide setting.