domingo, 22 de septiembre de 2013

Múltiples idiomas en tiempo de ejecución de la App.

Aunque no es muy común, en alguna ocasión puede que necesitemos que el usuario cambie el idioma de la App sin necesidad de cambiar el idioma del dispositivo. Hay varias soluciones en diferentes foros pero yo voy a explicar la que he utilizado en un proyecto recientemente, el cuento infantil brote brote (cuando esté publicada dejaré el link de la App). Es imprescindible que el proyecto tenga los diferentes Localizable.strings con las traducciones.

1. Creamos un contexto para la App. En esta ocasión, yo lo he incluido en un singleton de contexto ya que me influye en otros factores que no vienen al caso, pero se puede hacer perfectamente en NSUserDefault o en el mismo manager de idoma. Copio el archivo de cabecera seguido del de implementación.


#import <Foundation/Foundation.h>

@interface AppContext : NSObject

@property (nonatomic, strong) NSString *language;

+ (AppContext *)sharedInstance;

@end

A continuación el código de implementación:


#import "AppContext.h"

static AppContext *appContext = nil;

@implementation AppContext

@synthesize language;

+ (void)initialize
{
    NSAssert(self == [AppContext class],@"Esto es un singleton. Se explicará en posteriores artículos");
    appContext = [AppContext new];
}

+ (AppContext *)sharedInstance
{
    return appContext;
}

@end


2. Creamos nuestro manager de idioma. Será el encargado de decirle al path de la App qué carpeta de recurso quiere para el idioma.


#import <Foundation/Foundation.h>

@interface LanguageManager : NSObject

+(NSString*)languageSelectedStringForKey:(NSString*)key;

@end


A continuación el código de implementación:


#import "LanguageManager.h"
#import "AppContext.h"  

@implementation LanguageManager

+(NSString*)languageSelectedStringForKey:(NSString*)key
{
NSString *path;
    path = [[NSBundle mainBundle] pathForResource:[[AppContext sharedInstance] language] ofType:@"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString* string=[languageBundle localizedStringForKey:key value:@"" table:nil];
return string;
}

@end

3. Por último en el controlador encargado de modificar el idioma añadimos el método:

- (void)selectLanguage
{
    if(isLanguageSelected)
    {
        if([[[AppContext sharedInstance] language] isEqualToString:SPANISH])
            [[AppContext sharedInstance] setLanguage:ENGLISH];
        else if([[[AppContext sharedInstance] language] isEqualToString:ENGLISH])
            [[AppContext sharedInstance]setLanguage:DUTCH];
        else if ([[[AppContext sharedInstance] language] isEqualToString:DUTCH])
            [[AppContext sharedInstance] setLanguage:CHINESE];
        else
            [[AppContext sharedInstance] setLanguage:SPANISH];
            
    }
    else
    {
        NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
        
        if([language isEqualToString:@"es"])
        {
            [[AppContext sharedInstance] setLanguage:SPANISH];
        }
        else if ([language isEqualToString:@"de"])
        {
            [[AppContext sharedInstance] setLanguage:DUTCH];
        }
        else if([language isEqualToString:@"zh"])
        {
            [[AppContext sharedInstance] setLanguage:CHINESE];
        }
        else
        {
            [[AppContext sharedInstance] setLanguage:ENGLISH];
        }
    }
}

En nuestro caso como en nuestro mismo controlador queremos que se modifiquen algunas etiquetas

- (void)changeLanguage
{
    isLanguageSelected = TRUE;
    [self selectLanguage];
    
    [authorLabel setText:[LanguageManager languageSelectedStringForKey:@"authorLabel"]];
    [auxLabel setText:[LanguageManager languageSelectedStringForKey:@"titleAuxLabel"]];
    [titleLabel setText:[LanguageManager languageSelectedStringForKey:@"titleLabel"]];
    [subTitleLabel setText:[LanguageManager languageSelectedStringForKey:@"subTitleLabel"]];
    [languageButtonLabel setText:[LanguageManager languageSelectedStringForKey:@"languageTitle"]];
    [startButtonLabel setText:[LanguageManager languageSelectedStringForKey:@"startButton"]];
    [playButtonLabel setText:[LanguageManager languageSelectedStringForKey:@"playButton"]];
}





No hay comentarios:

Publicar un comentario