代码之家  ›  专栏  ›  技术社区  ›  Volker Voecking

在iOS中本地化字符串:默认(回退)语言?

  •  36
  • Volker Voecking  · 技术社区  · 16 年前

    例子: 我的应用程序已本地化为英语和德语:

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

    现在,如果我在UI语言设置为 Italian POWER_TO_THE_PEOPLE_BTN POWER_PLUG_BTN .

    从上面的例子可以清楚地看出,使用英文字符串作为键是行不通的。

    我现在看到的唯一选择就是 NSLocalizedStringWithDefaultValue 而不是 NSLocalizedString

    8 回复  |  直到 12 年前
        1
  •  18
  •   Community Mohan Dere    9 年前

    也许这会有帮助-- iPhone: localization / internationalization default strings file

    默认情况下,它应该返回到英语。我刚刚把手机换成了一种语言,我的应用程序没有本地化,而且文字都是英文,一如所料。

    重要提示: 正如@hyperspasm评论的那样:要扩展/重新表述这一点,回退语言是用户最近在设备设置中选择的语言,也在应用程序包中表示。

        2
  •  20
  •   Filip Dulic    14 年前

    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'

        3
  •  18
  •   Pattrawoot S.    11 年前

    您需要确保Info.plist中CFBundleDevelopmentRegion的值是您要回退到的语言区域(e、 “英语”)

        4
  •  5
  •   Makalele    8 年前

    @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)
    }
    
        5
  •  4
  •   Jonas Deichelmann RameshVel    7 年前

    Apple uses 为此,请定义替换它并在“overrided”方法中添加额外的回退逻辑。

    #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;
    }
    
        6
  •  2
  •   Community Mohan Dere    9 年前

    https://stackoverflow.com/a/25928309/3664461

    全球.h

    NSString * LString(NSString * translation_key);
    

    全球.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);
    

    另外,如果当前语言的特定键没有本地化,但它存在于基本地化中,则您将获得基本地化。

        7
  •  1
  •   beryllium    11 年前

    我已经创建了一个类别 NSBundle+FallbackLanguage 要支持回退语言,可以在 github folder

    #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
    
        8
  •  0
  •   Rikco    8 年前

    基于Bodus解决方案(thx btw),我创建了这个类别,因为您也需要“fallbackString”。所以我必须检查设备当前选择的语言,并将其与我想要支持的语言进行比较。只需导入标题,就可以使用默认宏

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

    在iOS9.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
    


    #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
    
        9
  •  0
  •   octobus Kuldeep Singh    6 年前

    老问题,但仍然是常青树。

    我们有一个 swift 4.2 快速解决方案强制应用程序 WHATEVER_THE_FALLBACK_LANGUAGE_WE_WANT_IT_TO_BE 退路。

    示例强制为“en”

    extension String {
    
      var localized: String {
    
        var preferred = "-"
        if let pl = NSLocale.preferredLanguages.first, let pref = pl.split(separator: "-").first { preferred = String(pref) } //<- selected device language or "-"
    
        guard let _ = Bundle.main.path(forResource: preferred, ofType: "lproj") else {
            //PREFERRED ISN'T LISTED. FALLING BACK TO EN
            guard let en_path = Bundle.main.path(forResource: "en", ofType: "lproj"), let languageBundle = Bundle(path: en_path) else {
                //EN ISN'T LISTED. RETURNING UNINTERNATIONALIZED STRING
                return self
            }
            //EN EXISTS
            return languageBundle.localizedString(forKey: self, value: self, table: nil)
        }
        //PREFERRED IS LISTED. STRAIGHT I18N IS OKAY
        return NSLocalizedString(self, comment: "")
      }
    
    }