Is there a way to change the iphone application language during runtime? - ios

My app supports localization for english and hungary languages.
I want to make default language as hungary instead of english if user sets default language other than english or hungary from phone settings .
For eg.If user's phone settings language is French,as my app is not support for french localization , so it should be launched in hungary as default not in english.
I have used following code in didFinishLaunchingWithOptions method in app delegate :
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"AppleLanguages"];
[NSUserDefaults resetStandardUserDefaults];
NSLog(#"%#",[NSLocale preferredLanguages]);
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([language isEqualToString:#"en"])
{
NSArray *langOrder = [NSArray arrayWithObjects:#"en", nil];
[[NSUserDefaults standardUserDefaults] setObject:langOrder forKey:#"AppleLanguages"];
}
else
{
NSArray *langOrder = [NSArray arrayWithObjects:#"hu", nil];
[[NSUserDefaults standardUserDefaults] setObject:langOrder forKey:#"AppleLanguages"];
}
So, after the change in the language from phone setting [[NSLocale preferredLanguages] objectAtIndex:0] immediately returns the string for the new language , ie. correct current language and also entered in correct condition in code.
But language will change only at second time relaunch of the app , not in first time launch.
So how can i do this ?
Thanks..

Related

iOS9 AppleLanguages different from older iOS

How I get now the actual system language? It seems that they put regional suffix after last dash. So before cs is now cs-DE if the language is Czech and regional setting is German. But there are some languages which don't have the suffix like GB language is en-GB but regional setting is German.
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* language = [defs objectForKey:#"AppleLanguages"];
NSString* preferredLang = [language objectAtIndex:0];
NSLog(#"localeIdentifier: %#", preferredLang);
Use the componentsFromLocaleIdentifier method from NSLocale class
Here is the documentation
You can do like this:
NSString* localeID = [NSLocale currentLocale].localeIdentifier;
NSDictionary* components = [NSLocale componentsFromLocaleIdentifier:localeID];
NSString* languageID = components[NSLocaleLanguageCode];
EDIT
Getting the language this way will create some issues if the language the app is currently translated in is not the device's language. Indeed,
components[NSLocaleLanguageCode] will return the device's language.
To get the app's current language, you should use [[NSBundle mainBundle] preferredLocalizations].firstObject.
To get the device's region, you can still use components[NSLocaleCountryCode]
I just run into this problem recently. According to Apple's documentation, you will get the locale id with region designator which for like [language designator]-[region designator] on iOS 9.
I found a solution if you just wanna get the locale id, you could use
[[NSBundle mainBundle] preferredLocalizations].
One more solution, If any of you like,
NSArray *languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
NSString *currentLanguage = [languages objectAtIndex:0];
if ([[currentLanguage componentsSeparatedByString:#"-"] count] == 2)
currentLanguage = [[currentLanguage componentsSeparatedByString:#"-"] objectAtIndex:0];
// Only for chinese Language.
else if ([[currentLanguage componentsSeparatedByString:#"-"] count] == 3)
currentLanguage = [NSString stringWithFormat:#"%#-%#", [[currentLanguage componentsSeparatedByString:#"-"] objectAtIndex:0],
[[currentLanguage componentsSeparatedByString:#"-"] objectAtIndex:1]
];
"currentLanguage" Will give you your current langauge so you can use it for localise or any further use.

GMSServices GMSGeocoder reverseGeocodeCoordinate language of returned results in IOS

I have two applications which used in pair and both used GMSGeocoder from GMSServices for reverseGeocodeCoordinate search. But in first one results are coming in english, on other - in device local language. Device is the same.
I searched a lot, and found that now is no ways to make GMSGeocoder use specified language for result. It is impossible and we should use google API requests instead. But it works somehow, and i have no idea how to make second application return results in english language only.
Similar concerns mapView - different languages on the same device.
How to set english for GMSServices regardless device localization?
GMSGeocoder sent you the county name, but not the country ISO code.
You can use native CLGeocoder class to get counytyISOcode from latitude and longitude. For example:
CLLocation *location = (your location)
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:
^(NSArray* placemarks, NSError* error){
if ([placemarks count] > 0)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"Your counry is %#",placemark. ISOcountryCode);
}
}];
Copy paste answer from stackoverflow.com/a/24333593/4195406
In - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
add
NSArray *languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
if (![[languages firstObject] isEqualToString:#"en"]) {
[[NSUserDefaults standardUserDefaults] setObject:#[#"en"] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
This works for me
In Addition to #Dren answer - it will help to add regionCode as well in the array
NSArray *languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
if (![[languages firstObject] isEqualToString:#"he"]) {
[[NSUserDefaults standardUserDefaults] setObject:#[#"he",#"he-IL"] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}

Will my app get rejected by apple if i use the following custom localization?

(Hint: I am just trying to make German as the default language when German or any other language is selected. Incase of French, it will show app in french language but for any othe language , it should show German.)
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"AppleLanguages"];
[NSUserDefaults resetStandardUserDefaults];
NSLog(#"%#",[NSLocale preferredLanguages]);
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([language isEqualToString:#"fr"])
{
NSArray *langOrder = [NSArray arrayWithObjects:#"fr", nil];
[[NSUserDefaults standardUserDefaults] setObject:langOrder forKey:#"AppleLanguages"];
}
else
{
NSArray *langOrder = [NSArray arrayWithObjects:#"de", nil];
[[NSUserDefaults standardUserDefaults] setObject:langOrder forKey:#"AppleLanguages"];
}
No, apple will not reject your app.
You can also read the rules for rejection of app from the following link: https://developer.apple.com/app-store/review/rejections/

Is it possible to "redirect" localizations on iOS?

What I want is simple:
My app has only two languages: English and Simplified Chinese. And I hope that if the system language is Simplified or Traditional Chinese, then Simplified Chinese is used; otherwise English is used.
It seems that most user don't know they can set their secondary preferred language. So I cannot rely on them.
You can use this code to retrieve the user language and set the app language:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Reset system defaults to get the complete language list.
[defaults removeObjectForKey:#"AppleLanguages"];
// Default language choosen by user.
NSString *defLanguage = [defaults objectForKey:#"Language"];
NSArray *sysLangugages = [defaults arrayForKey:#"AppleLanguages"];
// System default language: first element of array.
NSString *sysLanguage = [sysLangugages objectAtIndex:0];
NSArray *array = [NSArray arrayWithObjects:defLanguage, sysLanguage, nil];
LocalizationSetLanguage(defLanguage);
[defaults setObject:array forKey:#"AppleLanguages"];
//To set and get the saved language
// in the .h
#define LocalizationSetLanguage(language) \
[[LocalizationSystem sharedLocalSystem] setLanguage:(language)]
//in the .m
- (void) setLanguage:(NSString*) language
{
lang = language;
}
- (NSString*) getLanguage
{
if (!lang) {
NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
NSString *preferredLang = [languages objectAtIndex:0];
lang = preferredLang;
}
return lang;
}
Use AMLocalizedString, you can use this to set your local Language.

iOS localization - won't recognize es-US vs es-MX

I'm trying to show a different string for Mexican Spanish than US Spanish. The app always displays the US Spanish phrase. FYI - English, French and Portuguese work fine - but they don't have locales specified.
I created the localization folder in Build Settings->Localizations by clicking the + button, and selecting Spanish (Mexico)(es-MX) and Spanish (United States)(es-US) from the "Other" menu. I then updated the phrases appropriately. In the project I see 5 Localizable.strings files, including (Spanish-Mexico) and (Spanish-United States). Similarly I see the expected folders in Finder, including es-MX and es-US.
I put some NSLog messages in application didFinishLaunchingWithOptions:
NSLog(#"preferredLocalizations=%#", [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]);
NSLog(#"localization array=%#, count=%d", [[NSBundle mainBundle] preferredLocalizations], [[[NSBundle mainBundle] preferredLocalizations] count]);
NSLog(#"preferredLanguage = %#", [[NSLocale preferredLanguages] objectAtIndex:0]);
NSLog(#"language array=%#, count=%d", [NSLocale preferredLanguages], [[NSLocale preferredLanguages] count]);
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:#"AppleLanguages"];
NSString *current = [languages objectAtIndex:0];
NSLog(#"user default language=%#", current);
The output is:
2013-07-30 22:21:24.911 ecatalog[33497:907] application:didFinishLaunchingWithOptions
2013-07-30 22:21:24.918 ecatalog[33497:907] preferredLocalizations=es
2013-07-30 22:21:24.920 ecatalog[33497:907] localization array=(
es
), count=1
2013-07-30 22:21:24.922 ecatalog[33497:907] preferredLanguage = es
2013-07-30 22:21:24.924 ecatalog[33497:907] language array=(
es,
en,
fr, <snipped a bunch for brevity>
ms,
"en-GB",
ca,
hu,
vi
), count=34
2013-07-30 22:21:24.926 ecatalog[33497:907] user default language=es
The language array seems to the list of available languages on the phone, in my preferred order - i.e., if I set the phone for French, fr will be at the top of the list.
I don't know if its related, but my project includes two 3rd party frameworks which support Spanish, but just the es.lproj variation - not es-MX.lproj or es-US.lproj.
One other "symptom" - running the app in the simulator alternates between English and whatever language I have set the simulator to.
Thanks!
In my case I only have one string that needs to be different between Mexican and US Spanish, and it is only used in one place. So my work-around is to manually check the locale and hard-code the Mexican Spanish string:
NSString *startString;
// HACK - to diferentiate between Mexican Spanish and all others
NSLocale* curentLocale = [NSLocale currentLocale];
NSString *localId = [curentLocale localeIdentifier];
if ([localId isEqualToString: #"es_MX"]) {
// hard code a string
startString = #"Para seleccionar un folleto da clic +";
} else {
startString = NSLocalizedString(#"Click + to start!", nil);
}
It doesn't feel right, so if anyone has "the right way" I'd appreciate it.

Resources