I am expanding an existing iPhone app (4.x and up) with support for more languages: Estonian, Latvian and Lithuanian.
In my iPhone and in the simulator there is no support for these languages, and I am pretty sure that no special firmware exists for them either for use in those territories.
How can I best make an app that supports them?
I have come up with two solutions which I don't really like. Neither of them allows me to have more than one language in the app, since the user cannot choose the bundled languages from the Settings.app list. This means that one version must be submitted for each language.
For each targeted language (lt, lv, et) I put the strings files for that language into an en.lproj directory.
Pros: Uses a well-known mechanism. The app just thinks it is running English.
Cons: Wreaks havoc on my localization tools. Its confusing for future maintainers and therefore error prone. Requires a weird build setup.
The AppleLanguages
object in NSUserDefaults contains a list of languages for the app to use. By setting it like this I can get the app to load for example Lithuanian from an lt.lproj directory:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"lt", nil] forKey:@"AppleLanguages"];
(For historical reasons I am already doing a slightly more involved version of this to remove a deprecated translation in some versions of the app. Otherwise older installations would pick up the lproj dir even though I no longer bundle it with the app.)
Pros: Uses properly named lproj directories. Integrates well with localization tools. Simple setup. Only requires one line in main.m
to implement.
Cons: Even though the AppleLanguages
key is being used by a lot of people this solution uses it to load otherwise unsupported languages, so I fear I might be skating on thin ice.
AppleLanguages
hack?Why not adding language setting within your app then use this code (i use it in a project where the user can switch languages within the app after a requirement from my client).
It basically overwrites NSLocalizedString and uses the same file structure (en.lproj, etc.) for keeping the same language files you use when you use the "apple-way".
Give it a try!
.h file
#import <Foundation/Foundation.h>
//#undef NSLocalizedString
#define ___(key) \
[[I7I18N sharedInstance] localizedStringForKey:(key)]
#undef NSLocalizedString
#define NSLocalizedString(key,value) \
[[I7I18N sharedInstance] localizedStringForKey:(key)]
@interface I7I18N : NSObject
@property (nonatomic, retain) NSMutableDictionary *i18nTable;
+ (I7I18N *)sharedInstance;
- (NSString *)localizedStringForKey:(NSString *)key;
- (void)setLocale:(NSString *)lProjFile;
@end
.m file
#import "I7I18N.h"
static I7I18N *sharedInstance;
@implementation I7I18N
@synthesize i18nTable=_i18nTable;
+ (I7I18N *)sharedInstance {
if(!sharedInstance) {
sharedInstance = [[I7I18N alloc] init];
}
return sharedInstance;
}
- (id)init
{
self = [super init];
if (self) {
self.i18nTable = [NSMutableDictionary dictionary];
NSArray *validLocalizations = [[NSBundle mainBundle] localizations];
[self setLocale:[validLocalizations objectAtIndex:0]];
}
return self;
}
- (void)setLocale:(NSString *)lProjFile {
NSString *path = [[NSBundle mainBundle] pathForResource:@"Localizable.strings" ofType:@"" inDirectory:[NSString stringWithFormat:@"%@.lproj",lProjFile]];
self.i18nTable = [NSDictionary dictionaryWithContentsOfFile:path];
}
- (NSString *)localizedStringForKey:(NSString *)key {
NSString *possibleI18NString = [self.i18nTable objectForKey:key];
if(!possibleI18NString) {
return key;
}
return possibleI18NString;
}
@end
Update 1:
Do not forget to build all your view (all NSLocalizedString
dependencies when switching the language with [[I7I18N sharedInstance] setLocale:@"yourlang.lproj"]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With