Перевод приложения iOS на неподдерживаемые/нестандартные языки
Я расширяю существующее приложение iPhone (4.x и выше) с поддержкой большего количества языков: эстонский, латышский и литовский.
В моем iPhone и в симуляторе нет поддержки для этих языков, и я уверен, что для них не существует специальной прошивки либо для использования на этих территориях.
Как я могу лучше всего сделать приложение, которое их поддерживает?
Я придумал два решения, которые мне не нравятся. Ни один из них не позволяет мне иметь более одного языка в приложении, так как пользователь не может выбирать связанные языки из списка Settings.app. Это означает, что для каждого языка должна быть представлена одна версия.
Вариант 1: Нарушить каталог en.lproj
Для каждого целевого языка (lt, lv, et) я помещаю файлы строк для этого языка в каталог en.lproj.
Плюсы: Использует известный механизм. Приложение просто думает, что работает на английском языке.
Минусы: Наносит ущерб моим инструментам локализации. Его запутанность для будущих сопровождающих и, следовательно, склонность к ошибкам. Требуется странная настройка сборки.
Вариант 2: Злоупотребление NSUserDefaults [AppleLanguages]
Объект AppleLanguages
в NSUserDefaults содержит список языков для использования приложения. Установив его так, я могу загрузить приложение, например, литовский из каталога lt.lproj:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"lt", nil] forKey:@"AppleLanguages"];
(По историческим причинам, я уже делаю несколько более сложную версию этого, чтобы удалить устаревший перевод в некоторых версиях приложения. В противном случае старые установки подхватили бы lproj, даже если я больше не свяжу его с приложением. )
Плюсы: Использует правильно названные каталоги lproj. Интегрирует хорошо с инструментами локализации. Простая настройка. Для реализации требуется только одна строка в main.m
.
Минусы: Несмотря на то, что клавиша AppleLanguages
используется многими людьми, это решение использует его для загрузки в противном случае неподдерживаемых языков, поэтому я боюсь, что могу кататься на тонком льду.
Le Questions
- Как другие приложения обычно поддерживают эти "неподдерживаемые" языки?
- Есть ли способ поддерживать их вместе с нормально поддерживаемыми языками?
- Как вы относитесь к взлому
AppleLanguages
?
Ответы
Ответ 1
Почему бы не добавить настройки языка в вашем приложении, а затем использовать этот код (я использую его в проекте, где пользователь может переключать языки в приложении после требования моего клиента).
Он в основном перезаписывает NSLocalizedString и использует ту же файловую структуру (en.lproj и т.д.) для хранения тех же языковых файлов, которые вы используете, когда используете "яблочный путь".
Попробуйте!
.h файл
#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
Обновление 1:
Не забудьте создать все свои представления (все зависимости NSLocalizedString
при переключении языка с помощью [[I7I18N sharedInstance] setLocale:@"yourlang.lproj"]
.