iOS Localize app manually then switch

1.3k Views Asked by At

I have been facing a problem with iOS Programming since its the first time I'm using Localization,,

I used the following to know which lang I'm having:

- (NSString*) getLanguage{

NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];

NSString *preferredLang = [languages objectAtIndex:0];

return preferredLang;}

and there is button to change the lang That calls function to change the lang

- (void) setLanguage:(NSString*) l{
[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:l, nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults]synchronize];}

The language changes successfully, but I need to close and reopen the app to see the result, is there any other way to change the localisation automatically after switching lang?

NOTE: it should woke with storyboards too.

2

There are 2 best solutions below

2
On

As @Tudorizer describes in this link after you translate your files

use this solution:

Put this macro in the Prefix.pch:

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]

and where ever you need a localized string use:

NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"");

To set the language use:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];

Multiple times:

NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"fr"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"it"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
0
On

You can switch between languages in your application using the following class: (Note that anyway you should refresh content of all controllers stored in memory to get full effect.)

// AMLocalization.h

#define SetAppLanguage(language) [[AMLocalization sharedLocalization] setLanguage:language]
#define GetAppLanguage() [[AMLocalization sharedLocalization] language]
#define LSC(key, comment) [[AMLocalization sharedLocalization] localizedStringForKey:(key) value:(comment)]
#define UDKeyAppLanguage @"UDKeyAppLanguage"

typedef enum {
    UILanguageUnknown,
    UILanguageEnglish,
    UILanguageFrench,
    ..................
} UILanguage;

@interface AMLocalization : NSObject
+ (AMLocalization *)sharedLocalization;
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment;
- (BOOL) setLanguage:(UILanguage) lang;
- (UILanguage) language;
@end

// AMLocalization.m

#import "AMLocalization.h"

static AMLocalization *_s_sharedLocalization = nil;

@implementation AMLocalization {

    NSBundle *_bundle;
    NSDictionary *_languageSet;
}

+ (AMLocalization *)sharedLocalization
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        _s_sharedLocalization = [AMLocalization new];
    });
    return _s_sharedLocalization;
}

- (id) init
{
    if (self = [super init]) {
        _bundle = [NSBundle mainBundle];
        _languageSet = @{
                     @(UILanguageEnglish) : @"en",
                     @(UILanguageFrench) : @"fr"
                    };
    }
    return self;
}

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment
{
return [_bundle localizedStringForKey:key value:comment table:nil];
}

- (BOOL) setLanguage:(UILanguage) lang
{
    UILanguage activeLang = [self language];
    if (lang == UILanguageUnknown) {
        _bundle = [NSBundle mainBundle];
        [[NSUserDefaults standardUserDefaults] removeObjectForKey:UDKeyAppLanguage];
    }
    else {
        NSString *path = [[NSBundle mainBundle] pathForResource:_languageSet[@(lang)] ofType:@"lproj"];

        _bundle = [NSBundle bundleWithPath:path];
        [[NSUserDefaults standardUserDefaults] setInteger:lang forKey:UDKeyAppLanguage];
    }
    [[NSUserDefaults standardUserDefaults] synchronize];

    return activeLang != lang;
}

- (UILanguage) language
{
    UILanguage lang = [[NSUserDefaults standardUserDefaults] integerForKey:UDKeyAppLanguage];
    if (lang == UILanguageUnknown) {
        NSString* preferredLang = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"][0];
        for (NSNumber *key in _languageSet) {
            if ([_languageSet[key] isEqualToString:preferredLang]) {
                lang = [key integerValue];
                break;
            }
        }
    }
    return lang;
}

@end