Перевод приложения 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"].