Локализация строк в iOS: язык по умолчанию (резервный)? - PullRequest
38 голосов
/ 16 июля 2010

Есть ли способ установить язык по умолчанию, который будет использоваться, когда язык интерфейса устройства не поддерживается приложением?

Пример: Мое приложение локализовано на английский и немецкий языки:

// en.lproj:
"POWER_TO_THE_PEOPLE_BTN" = "Power";
"POWER_PLUG_BTN" = "Power";

// de.lproj:
"POWER_TO_THE_PEOPLE_BTN"  = "Macht";
"POWER_PLUG_BTN" = "Spannung";

Теперь, если я запускаю приложение на устройстве с языком пользовательского интерфейса, установленным на Italian, приложение будет использовать строки ключей POWER_TO_THE_PEOPLE_BTN и POWER_PLUG_BTN.

Должен быть способ указать язык по умолчанию (резервный), который будет использоваться приложением в таком случае.

Из приведенного выше примера должно быть ясно, что использование английской строки в качестве ключа не будет работать.

Единственный вариант, который я вижу сейчас, - это использовать NSLocalizedStringWithDefaultValue вместо NSLocalizedString.

Ответы [ 8 ]

18 голосов
/ 09 января 2012

Чтобы избежать всего этого длинного синтаксиса и того, чтобы у переводчиков было более описательное имя переменной, я получил свой собственный вспомогательный метод L() для перевода и возврата к английскому

NSString * L(NSString * translation_key) {
    NSString * s = NSLocalizedString(translation_key, nil);
    if (![[[NSLocale preferredLanguages] objectAtIndex:0] isEqualToString:@"en"] && [s isEqualToString:translation_key]) {
    NSString * path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
    NSBundle * languageBundle = [NSBundle bundleWithPath:path];
    s = [languageBundle localizedStringForKey:translation_key value:@"" table:nil];
    }
    return s;
}

Мой Localizable.strings будет выглядетьвот так

"SOME_ACTION_BUTTON" = "Do action";

Так что в моем коде я бы использовал L(@"SOME_ACTION_BUTTON") для получения правильной строки

Хотя иногда ключ длиннее самого перевода HELP_BUTTON_IN_NAV_BAR = 'Help', но это спасает менямного времени объясняю, что это за тот, кто помогает мне делать перевод

17 голосов
/ 20 октября 2014

Вы должны убедиться, что значение CFBundleDevelopmentRegion в вашем Info.plist является языковой областью, к которой вы хотели бы вернуться.(например, "en")

13 голосов
/ 25 июля 2010

Возможно, это должно помочь?- iPhone: файл строк по умолчанию для локализации / интернационализации

По умолчанию он должен быть выполнен на английском языке.Я только что переключил свой телефон на язык, на котором мое приложение не локализовано, и текст был полностью на английском, как и ожидалось.

Важно: , как заметил @hyperspasm: РасширитьПерефразируя это, резервный язык - это язык, который последний раз выбирал пользователь в настройках устройства, который также представлен в комплекте приложения.

2 голосов
/ 23 ноября 2017

@ Поддельный ответ в Swift 4, работает как шарм на iOS 11.1:

public func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String {
    let fallbackLanguage = "en"
    guard let fallbackBundlePath = Bundle.main.path(forResource: fallbackLanguage, ofType: "lproj") else { return key }
    guard let fallbackBundle = Bundle(path: fallbackBundlePath) else { return key }
    let fallbackString = fallbackBundle.localizedString(forKey: key, value: comment, table: nil)
    return Bundle.main.localizedString(forKey: key, value: fallbackString, table: nil)
}
2 голосов
/ 27 июля 2016

Мое решение благодаря https://stackoverflow.com/a/25928309/3664461

Global.h

NSString * LString(NSString * translation_key);

Global.m

NSString *LString(NSString *translation_key) {
  NSString *lString = nil;
  NSString *languageCode = nil;

  if ([UIDevice currentDevice].systemVersion.floatValue >= 9) {
    NSString *localeIdentifier = [[NSLocale preferredLanguages] objectAtIndex:0];
    NSDictionary *localeDic = [NSLocale componentsFromLocaleIdentifier:localeIdentifier];
    languageCode = [localeDic objectForKey:@"kCFLocaleLanguageCodeKey"];
  } else {
    languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
  }

  NSString *path = [[NSBundle mainBundle] pathForResource:languageCode ofType:@"lproj"];
  if (path != nil) {
    lString = NSLocalizedStringFromTableInBundle(translation_key, @"Localizable",
                                             [NSBundle bundleWithPath:path], @"");
  }

   path = [[NSBundle mainBundle] pathForResource:@"Base" ofType:@"lproj"];
   lString = NSLocalizedStringFromTableInBundle(translation_key, @"Localizable",
                                             [NSBundle bundleWithPath:path], @"");
  }
  return lString;
}

Использование:

#import "Global.h"
printf(LString(@"MyKey").UTF8String);

Это решение не учитывает порядок предпочтений пользователей.Вместо этого он всегда будет возвращаться к тому, что есть в Base, если язык пользователя не локализован.Также, если определенный ключ не локализован для текущего языка, но существует в базовой локализации, вы получите базовую локализацию.

Обновление:

Начиная с iOS 9, регион включен вязыковые локали.Я обновил код, чтобы справиться с этим.

2 голосов
/ 23 августа 2014

Быстрый способ сделать это без замены каких-либо методов - это "переопределить" определение NSLocalizedString и использовать методы, которые Apple использует для этого определения, чтобы заменить его и добавить дополнительную резервную логику в "переопределенном" метод.

#undef NSLocalizedString
#define NSLocalizedString(key, comment) [self localizedStringForKey:(key) replaceValue:(comment)]

+ (NSString *)localizedStringForKey:(NSString *)key replaceValue:(NSString *)comment {
    NSString *fallbackLanguage = @"en";
    NSString *fallbackBundlePath = [[NSBundle mainBundle] pathForResource:fallbackLanguage ofType:@"lproj"];    
    NSBundle *fallbackBundle = [NSBundle bundleWithPath:fallbackBundlePath];
    NSString *fallbackString = [fallbackBundle localizedStringForKey:key value:comment table:nil];    
    NSString *localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:fallbackString table:nil];

    return localizedString;
}
1 голос
/ 13 октября 2014

Я создал категорию NSBundle+FallbackLanguage для поддержки резервного языка, вы можете проверить ее в папке github . Вам нужно только указать массив поддерживаемых языков в реализации.

NSBundle + FallbackLanguage.h

#import <Foundation/Foundation.h>

#undef NSLocalizedString
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) replaceValue:(comment)]

@interface NSBundle (FallbackLanguage)

- (NSString *)localizedStringForKey:(NSString *)key replaceValue:(NSString *)comment;

@end

NSBundle + FallbackLanguage.m

#import "NSBundle+FallbackLanguage.h"

@implementation NSBundle (FallbackLanguage)

- (NSString *)localizedStringForKey:(NSString *)key replaceValue:(NSString *)comment {        
    NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
    NSString *localizedString;

    if ([@[@"en", @"de", @"fr"] containsObject:language]){
        localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil];
    }
    else{
        NSString *fallbackLanguage = @"en";
        NSString *falbackBundlePath = [[NSBundle mainBundle] pathForResource:fallbackLanguage ofType:@"lproj"];
        NSBundle *fallbackBundle = [NSBundle bundleWithPath:falbackBundlePath];
        NSString *fallbackString = [fallbackBundle localizedStringForKey:key value:comment table:nil];
        localizedString = fallbackString;
    }

    return localizedString;
}

@end
0 голосов
/ 15 ноября 2017

На основе решения Bodus (thx btw.) Я создал эту категорию, потому что вам также нужна "fallbackString". Поэтому я должен проверить текущий выбранный язык устройства и сравнить его с моими языками, которые я хочу поддерживать. Просто импортируйте заголовок, и вы можете использовать яблочный макрос по умолчанию

NSString *myString = NSLocalizedString(@"My Ub0rstring", nil);

Отлично работает на iOS 9.x и 11.1.

NSString + helper.h

#import <Foundation/Foundation.h>

#undef NSLocalizedString
#define NSLocalizedString(key, comment) [NSString localizedStringForKey:(key) replaceValue:(comment)]

@interface NSString (Helper)

+ (NSString *)localizedStringForKey:(NSString *)key replaceValue:(NSString *)comment;

@end


NSString + Helper.m

#import "NSString+Helper.h"

@implementation NSString (Helper)

+ (NSString *)localizedStringForKey:(NSString *)key replaceValue:(NSString *)comment
{
    NSString *fallbackLanguage      = @"en";
    NSString *fallbackBundlePath    = [[NSBundle mainBundle] pathForResource:fallbackLanguage ofType:@"lproj"];
    NSBundle *fallbackBundle        = [NSBundle bundleWithPath:fallbackBundlePath];
    NSString *fallbackString        = [fallbackBundle localizedStringForKey:key value:comment table:nil];
    NSString *localizedString       = [[NSBundle mainBundle] localizedStringForKey:key value:fallbackString table:nil];

    NSString *language              = [[NSLocale preferredLanguages] firstObject];
    NSDictionary *languageDic       = [NSLocale componentsFromLocaleIdentifier:language];
    NSString *languageCode          = [languageDic objectForKey:@"kCFLocaleLanguageCodeKey"];

    if ([languageCode isEqualToString:@"de"] || [languageCode isEqualToString:@"en"]) {
        return localizedString;
    }
    else {
        return fallbackString;
    }
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...