42 Stimmen

Lokalisierung von Zeichenketten in iOS: Standardsprache (Fallback)?

Gibt es eine Möglichkeit, eine Standardsprache festzulegen, die verwendet wird, wenn die Sprache der Geräteoberfläche von einer Anwendung nicht unterstützt wird?

Beispiel: Meine App ist auf Englisch und Deutsch lokalisiert:

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

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

Wenn ich nun die Anwendung auf einem Gerät ausführe, bei dem die UI-Sprache auf Italian wird die Anwendung die Schlüsselstrings verwenden POWER_TO_THE_PEOPLE_BTN y POWER_PLUG_BTN .

Es muss eine Möglichkeit geben, eine Standardsprache (Fallback) anzugeben, die von der Anwendung in einem solchen Fall verwendet wird.

Aus dem obigen Beispiel sollte ersichtlich sein, dass die Verwendung der englischen Zeichenfolge als Schlüssel nicht funktionieren wird.

Die einzige Möglichkeit, die ich im Moment sehe, ist die Verwendung von NSLocalizedStringWithDefaultValue 代わりに NSLocalizedString .

2voto

Siamaster Punkte 924

Meine Lösung dank 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;
}

Verwendung:

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

Bei dieser Lösung wird die Reihenfolge der Benutzerpräferenzen nicht berücksichtigt. Stattdessen wird immer auf die unter Base eingestellte Sprache zurückgegriffen, wenn die erste Sprache des Benutzers nicht lokalisiert ist. Auch wenn eine bestimmte Taste für die aktuelle Sprache nicht lokalisiert ist, sie aber in der Basislokalisierung vorhanden ist, wird die Basislokalisierung verwendet.

Aktualisierung:

Seit iOS 9 ist die Region in den Sprachumgebungen enthalten. Ich habe den Code aktualisiert, um dies zu berücksichtigen.

1voto

beryllium Punkte 29485

Ich habe die Kategorie NSBundle+FallbackLanguage zur Unterstützung der Fallback-Sprache, können Sie es auf der Github-Ordner . Sie müssen nur die Reihe der unterstützten Sprachen in der Implementierung angeben.

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

0voto

Rikco Punkte 367

Basierend auf Bodus Lösung (danke btw.) habe ich diese Kategorie erstellt, weil man den "fallbackString" auch braucht. Ich muss also die aktuell ausgewählte Sprache des Geräts überprüfen und mit den Sprachen vergleichen, die ich unterstützen möchte. Importieren Sie einfach den Header und Sie können Apfels Standardmakro verwenden

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

Funktioniert gut unter iOS 9.x und 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

0voto

Dome Santoro Punkte 1

Ein altes Thema, aber immer noch ein Evergreen.

Hier sind wir mit einer swift 4.2 schnelle Lösung, um die Anwendung auf einer WHATEVER_THE_FALLBACK_LANGUAGE_WE_WANT_IT_TO_BE Fallback.

Das Beispiel zwingt zu "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: "")
  }

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X