3

I have localized my app using the localization feature in iOS, I have added Localizable.strings files (English and Spanish) in my project.

So far the app was behaving nicely, found the following issue

After a while when switching the device/simulator to spanish the app is still in english or vice versa. I have been logging the following

NSLog(@"Preferred Language : %@", [[NSLocale preferredLanguages] objectAtIndex:0]);
NSLog(@"Locale Identifier : %@", [[NSLocale currentLocale] localeIdentifier]);
NSLog(@"NSUserDefaults AppleLanguages : %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"]);

Before the app reaches to this issue has the following output

Preferred Language : en
Locale Identifier : en_US
NSUserDefaults AppleLanguages : (
en,
es,
de,
fr,
ja,
nl,
it,
pt,
"pt-PT",
da,
fi,
nb,
sv,
ko,
"zh-Hans",
"zh-Hant",
ru,
pl,
tr,
uk,
ar,
hr,
cs,
el,
he,
ro,
sk,
th,
id,
ms,
"en-GB",
ca,
hu,
vi
) 

then after a while (even if I have switched successfully the language) when switching again the app to spanish the AppleLanguages array in NSUserDefaults has only one language, in this case english (en).

Preferred Language : en
Locale Identifier : en_US
NSUserDefaults AppleLanguages : (
en
)

This is causing the app to be displayed per the only preferred language which is the first element in the AppleLanguages array. So far I'm not changing or modifying the AppleLanguages array in NSUserDefaults anywhere in the code. The only thing I'm forcing is to load the english bundle for the Localizable.string file with the following code

NSBundle *englishBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"]]; 
NSString *localizedString = NSLocalizedStringFromTableInBundle(@"Key to localize", nil, englishBundle, @"");

I commented this code thinking that probably was messing the NSUserDefaults AppleLanguages array but the issue persist. I wonder what exactly is causing this issue or if probably I'm missing something in the project configuration.

EDIT (1)

So far I have found that the Info.plist file that stores the NSUserDefaults properties for the app, for some reason is saving the AppleLanguages with just one language item regardless that in the entire code I'm not overriding the AppleLanguages array.

Temporally I have added the following code in applicationDidEnterBackground

[[NSUserDefaults standardDefaults] setObject:nil forKey:@"AppleLanguages"];
[[NSUserDefaults standardDefaults] synchronize];

By doing the workaround above I have forced the app to always remove the AppleLanguages from the Info.plist file, so far I have found that this issue is only happened in iOS 7.0 to iOS 7.02, I'm still testing in different iOS versions, I don't want to assume that this is an iOS bug but probably a misconfiguration in my project that so far I have not been able to identify or reproduce.

Black Sheep
  • 1,665
  • 1
  • 22
  • 32

3 Answers3

0

Maybe after changing the language to Spanish, you need to restart the app.

fumoboy007
  • 5,345
  • 4
  • 32
  • 49
0

I have this code in one of my projects:

NSString* localizedStringFromBundle(NSString *key)
{
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *localeCode = [[NSLocale autoupdatingCurrentLocale] localeIdentifier];
    NSString *languageCode = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode];
    NSString *localizedString = key;
    BOOL found = NO;
    if ([[bundle localizations] indexOfObject:languageCode] == NSNotFound &&
        [[bundle localizations] indexOfObject:localeCode] == NSNotFound)
    {
        return [bundle localizedStringForKey:key value:nil table:@"en.lproj/Localizable"];
    }

    if ([[bundle localizations] indexOfObject:localeCode] != NSNotFound)
    {
        NSString *translationTableName = [localeCode stringByAppendingString:@".lproj/Localizable"];
        localizedString = [bundle localizedStringForKey:key value:nil table:translationTableName];
        found = ![localizedString isEqualToString:key];
    }

    if (!found)
    {
        NSString *translationTableName = [languageCode stringByAppendingString:@".lproj/Localizable"];
        localizedString = [bundle localizedStringForKey:key value:nil table:translationTableName];
        if ([localizedString isEqualToString:key])
        {
            localizedString = [bundle localizedStringForKey:key value:nil table:@"en.lproj/Localizable"];
        }
        else
            NSLog(@"Missing string for key: %@, returning string: %@", key, localizedString);
    }
    return localizedString;
}
  • Thanks, but noticed that your solution is using the `currentLocale` instead the `preferredLanguages` I think the right approach is to localize the app by using the user preferred language and for number formatting use the region/locale. – Black Sheep Mar 15 '14 at 23:15
0

In iOS 13 or newer, the language selection can be made on a "per app" based via the Settings app.

New features available with iOS 13:

Language selection per app

Use third‑party apps in a different language from your system language.

marc-medley
  • 8,931
  • 5
  • 60
  • 66