Lokalisierung in Xamarin.iOS

Dieses Dokument behandelt die Lokalisierungsfeatures des iOS-SDKs und wie Sie mit Xamarin darauf zugreifen können.

Anweisungen zum Einschließen von Zeichensätzen/Codepages in Anwendungen, die Nicht-Unicode-Daten verarbeiten müssen, finden Sie in den Codierungen für die Internationalisierung.

iOS-Plattformfeatures

In diesem Abschnitt werden einige der Lokalisierungsfeatures in iOS beschrieben. Springen Sie zum nächsten Abschnitt, um spezifischen Code und Beispiele anzuzeigen.

Sprache

Benutzer*innen wählen ihre Sprache in der Einstellungen-App aus. Diese Einstellung wirkt sich auf die Sprachzeichenfolgen und Bilder aus, die vom Betriebssystem und in Apps angezeigt werden.

Um die in einer App verwendete Sprache zu ermitteln, rufen Sie das erste Element von NSBundle.MainBundle.PreferredLocalizations ab:

var lang = NSBundle.MainBundle.PreferredLocalizations[0];

Dieser Wert wird ein Sprachcode sein, z. B. en für Englisch, es für Spanisch, ja für Japanisch usw. Der zurückgegebene Wert ist auf eine der von der Anwendung unterstützten Lokalisierungen beschränkt (mithilfe von Fallbackregeln, um die beste Übereinstimmung zu ermitteln).

Anwendungscode muss nicht immer nach diesem Wert prüfen – Xamarin und iOS bieten beide Features, die helfen, automatisch die richtige Zeichenfolge oder Ressource für die Sprache der Benutzer*innen bereitzustellen. Diese Features werden im restlichen Teil dieses Dokuments beschrieben.

Hinweis

Verwenden Sie NSLocale.PreferredLanguages, um die Spracheinstellungen von Benutzer*innen unabhängig von den von der App unterstützten Lokalisierungen zu ermitteln. Die von dieser Methode zurückgegebenen Werte wurden in iOS 9 geändert, weitere Informationen finden Sie im Technischen Hinweis TN2418.

Gebietsschema

Benutzer*innen wählen ihr Gebietsschema in der Einstellungen-App aus. Diese Einstellung wirkt sich auf die Art und Weise aus, wie Datumsangaben, Uhrzeiten, Zahlen und Währungen formatiert werden.

Auf diese Weise können Benutzer*innen auswählen, ob 12-Stunden- oder 24-Stunden-Zeitformate angezeigt werden, ob ihr Dezimaltrennzeichen ein Komma oder ein Punkt ist, und die Reihenfolge von Tag, Monat und Jahr in der Datumsanzeige.

Mit Xamarin haben Sie Zugriff auf die iOS-Klassen (NSNumberFormatter) von Apple sowie auf die .NET-Klassen in System.Globalization. Entwickler*innen sollten abwägen, welche für ihre Anforderungen besser geeignet sind, da in den einzelnen Klassen unterschiedliche Features zur Verfügung stehen. Insbesondere wenn Sie In-App-Einkaufspreise mithilfe von StoreKit abrufen und anzeigen, sollten Sie die Formatierungsklassen von Apple für die zurückgegebenen Preisinformationen verwenden.

Das aktuelle Gebietsschema kann auf zwei Arten abgefragt werden:

  • NSLocale.CurrentLocale.LocaleIdentifier
  • NSLocale.AutoUpdatingCurrentLocale.LocaleIdentifier

Der erste Wert kann vom Betriebssystem zwischengespeichert werden und spiegelt daher möglicherweise nicht immer das aktuell ausgewählte Gebietsschema der Benutzer*innen wider. Verwenden Sie den zweiten Wert, um das aktuell ausgewählte Gebietsschema abzurufen.

Hinweis

Mono (die .NET-Runtime, auf der Xamarin.iOS basiert) und die iOS-APIs von Apple unterstützen keine identischen Kombinationen von Sprache/Region. Aus diesem Gründen ist es möglich, eine Kombination von Sprache/Region in der iOS-Einstellungen-App auszuwählen, die keinem gültigen Wert in Mono zugeordnet ist. Das Festlegen der Sprache eines iPhones auf Englisch und seine Region auf Spanien führt beispielsweise dazu, dass die folgenden APIs unterschiedliche Werte liefern:

  • CurrentThead.CurrentCulture: en-US (Mono-API)
  • CurrentThread.CurrentUICulture: en-US (Mono-API)
  • NSLocale.CurrentLocale.LocaleIdentifier: en_ES (Apple-API)

Da Mono CurrentThread.CurrentUICulture zum Auswählen von Ressourcen und CurrentThread.CurrentCulture zum Formatieren von Datumsangaben und Währungen verwendet, kann es sein, dass die auf Mono basierte Lokalisierung (z. B. mit RESX-Dateien) keine erwarteten Ergebnisse für diese Kombination von Sprache/Region liefert. Verlassen Sie sich in diesen Situationen auf die APIs von Apple, um nach Bedarf zu lokalisieren.

NSCurrentLocaleDidChangeNotification

iOS generiert ein NSCurrentLocaleDidChangeNotification, wenn Benutzer*innen ihr Gebietsschema aktualisieren. Anwendungen können während der Ausführung auf diese Benachrichtigung lauschen und entsprechende Änderungen an der Benutzeroberfläche vornehmen.

Lokalisierungsgrundlagen in iOS

Die folgenden Features von iOS lassen sich in Xamarin leicht nutzen, um lokalisierte Ressourcen für die Anzeige für Benutzer*innen bereitzustellen. Im TaskyL10n-Beispiel erfahren Sie, wie Sie diese Ideen implementieren.

Angeben von Standard- und unterstützten Sprachen in Info.plist

Im Technischen Q&A QA1828: Wie iOS die Sprache für Ihre App bestimmt beschreibt Apple, wie iOS eine Sprache auswählt, die in einer App verwendet werden soll. Die folgenden Faktoren beeinflussen, welche Sprache angezeigt wird:

  • Die bevorzugten Sprachen der Benutzer*innen (in der Einstellungen-App gefunden)
  • Die mit der App gebündelten Lokalisierungen (.lproj-Ordner)
  • CFBundleDevelopmentRegion (Info.plist-Wert, der die Standardsprache für die App angibt)
  • CFBundleLocalizations (Info.plist-Array, das alle unterstützten Lokalisierungen angibt)

Wie im technischen Q&A angegeben, stellt CFBundleDevelopmentRegion die Standardregion und -sprache einer App dar. Wenn die App keine der bevorzugten Sprachen von Benutzer*innen explizit unterstützt, wird sie die in diesem Feld angegebene Sprache verwendet.

Wichtig

iOS 11 wendet diesen Sprachauswahlmechanismus strenger an als frühere Versionen des Betriebssystems. Aus diesem Grund kann jede iOS 11-App, die ihre unterstützten Lokalisierungen nicht explizit deklariert – entweder durch Einschließen von .lproj-Ordnern oder festlegen eines Werts für CFBundleLocalizations – unter iOS 11 eine andere Sprache anzeigen als unter iOS 10.

Wenn CFBundleDevelopmentRegion in der Datei Info.plist nicht angegeben wurde, verwenden die Xamarin.iOS-Buildtools derzeit einen Standardwert von en_US. Obwohl sich dies in einem zukünftigen Release ändern kann, bedeutet dies, dass die Standardsprache Englisch ist.

Führen Sie die folgenden Schritte aus, um sicherzustellen, dass Ihre App eine erwartete Sprache auswählt:

  • Geben Sie eine Standardsprache an. Öffnen Sie Info.plist, und verwenden Sie die Ansicht Quelle, um einen Wert für den CFBundleDevelopmentRegion-Schlüssel festzulegen. In XML sollte dies ähnlich wie das Folgende aussehen:
<key>CFBundleDevelopmentRegion</key>
<string>es</string>

In diesem Beispiel wird „es“ verwendet, um anzugeben, dass standardmäßig Spanisch verwendet wird, wenn keine der bevorzugten Sprachen der Benutzer*innen unterstützt wird.

  • Deklarieren Sie alle unterstützten Lokalisierungen. Verwenden Sie in Info.plist die Ansicht Quelle, um ein Array für den CFBundleLocalizations-Schlüssel festzulegen. In XML sollte dies ähnlich wie das Folgende aussehen:
<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>es</string>
    ...
</array>

Xamarin.iOS-Apps, die mithilfe von .NET-Mechanismen wie RESX-Dateien lokalisiert wurden, müssen diese Info.plist-Werte ebenfalls bereitstellen.

Weitere Informationen zu diesen Info.plist-Schlüsseln finden Sie in der Schlüsselreferenz zur Informationseigenschaftenlistevon Apple.

GetLocalizedString-Methode

Die NSBundle.MainBundle.GetLocalizedString-Methode sucht lokalisierten Text, der in .strings-Dateien im Projekt gespeichert wurde. Diese Dateien sind nach Sprache organisiert, in speziell benannten Verzeichnissen mit einem .lproj-Suffix (beachten Sie, dass der erste Buchstabe der Erweiterung ein Kleinbuchstabe „L“ ist).

.strings-Dateispeicherorte

  • Base.lproj ist das Verzeichnis, das Ressourcen für die Standardsprache enthält. Es befindet sich häufig im Projektstamm (kann sich aber auch im Ordner Ressourcen befinden).
  • <language>.lproj-Verzeichnisse werden für jede unterstützte Sprache erstellt, in der Regel im Ordner Ressourcen.

Es kann eine Reihe verschiedener .strings-Dateien in jedem Sprachverzeichnis geben:

  • Localizable.strings – die Hauptliste von lokalisiertem Text.
  • InfoPlist.strings – bestimmte spezifische Schlüssel sind in dieser Datei zulässig, um Dinge wie den Anwendungsnamen zu übersetzen.
  • <storyboard-name>.strings – optionale Datei, die Übersetzungen für Benutzeroberflächenelemente in einem Storyboard enthält.

Die Buildaktion für diese Dateien sollte Ressourcen bündeln sein.

.strings-Dateiformat

Die Syntax für lokalisierte Zeichenfolgenwerte lautet:

/* comment */
"key"="localized-value";

Sie sollten die folgenden Zeichen in Zeichenfolgen escapen:

  • Zitat von \"
  • \\ umgekehrter Schrägstrich
  • \n Zeilenvorschubzeichen

Dies ist ein Beispiel für die Datei es/Localizable.strings (d.h. Spanisch) aus dem Beispiel:

"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";

Bilder

So lokalisieren Sie ein Bild in iOS:

  1. Verweisen Sie auf das Bild im Code, z. B.:

    UIImage.FromBundle("flag");
    
  2. Platzieren Sie die Standardbilddatei flag.png in Base.lproj (das Verzeichnis der nativen Entwicklungssprache).

  3. Platzieren Sie optional lokalisierte Versionen des Bildes in .lproj-Ordnern für jede Sprache (z. B. es.lproj, ja.lproj). Verwenden Sie in jedem Sprachverzeichnis denselben Dateinamen flag.png.

Wenn ein Bild für eine bestimmte Sprache nicht vorhanden ist, wird iOS ein Fallback auf den Standardordner für die native Sprache durchführen und das Bild von dort laden.

Startbilder

Verwenden Sie die Standardnamenskonventionen für die Startbilder (und das XIB oder Storyboard für iPhone 6-Modelle), wenn Sie diese in den .lproj-Verzeichnissen für jede Sprache platzieren.

Default.png
Default@2x.png
Default-568h@2x.png
LaunchScreen.xib

App-Name

Wenn Sie eine InfoPlist.strings-Datei in einem .lproj-Verzeichnis platzieren, können Sie einige Werte aus der Info.plist der App überschreiben, einschließlich des Anwendungsnamens:

"CFBundleDisplayName" = "LeónTodo";

Andere Schlüssel, die Sie zum Lokalisieren anwendungsspezifischer Zeichenfolgen verwenden können, sind:

  • CFBundleName
  • CFBundleShortVersionString
  • NSHumanReadableCopyright

Datums- und Zeitangaben

Obwohl es möglich ist, die integrierten .NET-Datums- und Uhrzeitfunktionen (zusammen mit dem aktuellen CultureInfo) zum Formatieren von Datums- und Uhrzeitangaben für ein Gebietsschema zu verwenden, würde dies gebietsschemaspezifische Benutzereinstellungen ignorieren (die separat von der Sprache festgelegt werden können).

Verwenden Sie den iOS-NSDateFormatter, um eine Ausgabe zu erzeugen, die der Gebietsschemaeinstellung der Benutzer*innen entspricht. Der folgende Beispielcode veranschaulicht die grundlegenden Formatierungsoptionen für Datum und Uhrzeit:

var date = NSDate.Now;
var df = new NSDateFormatter ();
df.DateStyle = NSDateFormatterStyle.Full;
df.TimeStyle = NSDateFormatterStyle.Long;
Debug.WriteLine ("Full,Long: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Short;
df.TimeStyle = NSDateFormatterStyle.Short;
Debug.WriteLine ("Short,Short: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Medium;
df.TimeStyle = NSDateFormatterStyle.None;
Debug.WriteLine ("Medium,None: " + df.StringFor(date));

Ergebnisse für Englisch in den USA:

Full,Long: Friday, August 7, 2015 at 10:29:32 AM PDT
Short,Short: 8/7/15, 10:29 AM
Medium,None: Aug 7, 2015

Ergebnisse für Spanisch in Spanien:

Full,Long: viernes, 7 de agosto de 2015, 10:26:58 GMT-7
Short,Short: 7/8/15 10:26
Medium,None: 7/8/2015

Weitere Informationen finden Sie in der Apple-Dokumentation Datumsformatierer. Überprüfen Sie beim Testen der Gebietsschema-sensitiven Datums- und Uhrzeitformatierung sowohl die Einstellungen für die iPhone-Sprache als auch die Region.

Layout von rechts nach links (Right-To-Left, RTL)

iOS bietet eine Reihe von Features zur Unterstützung beim Erstellen von RTL-fähigen Apps:

  • Verwenden Sie die leading- und trailing-Attribute der automatischen Layouts für die Ausrichtung der Steuerelemente (die für Englisch links nach rechts entspricht, aber für RTL-Sprachen umgekehrt ist). Das UIStackView-Steuerelement ist besonders nützlich, um Steuerelemente RTL-fähig zu gestalten.
  • Verwenden Sie TextAlignment = UITextAlignment.Natural für die Textausrichtung (wird für die meisten Sprachen links, aber für RTL rechts sein).
  • UINavigationController spiegelt die „Zurück“-Schaltfläche automatisch und kehrt die Wischrichtung um.

Die folgenden Screenshots zeigen das lokalisierte Tasky-Beispiel in Arabisch und Hebräisch (obwohl Englisch in die Felder eingegeben wurde):

Localization in Arabic

Localization in Hebrew

iOS kehrt das UINavigationController automatisch um, und die anderen Steuerelemente werden innerhalb von UIStackView platziert oder mit Auto-Layout ausgerichtet. RTL-Text wird mit .strings-Dateien auf die gleiche Weise wie LTR-Text lokalisiert.

Lokalisieren der Benutzeroberfläche im Code

Das Beispiel Tasky (lokalisiert im Code) zeigt, wie Sie eine Anwendung lokalisieren, in der die Benutzeroberfläche in Code (anstelle von XIBs oder Storyboards) integriert ist.

Projektstruktur

Screenshot shows the resources tree for a sample including the location of localizable strings.

Localizable.strings-Datei

Wie oben beschrieben, besteht das Dateiformat Localizable.strings aus Schlüssel-Wert-Paaren. Der Schlüssel beschreibt die Absicht der Zeichenfolge und der Wert ist der übersetzte Text, der in der App verwendet werden soll.

Die Lokalisierungen für Spanisch (es) für das Beispiel werden unten gezeigt:

"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";

Durchführen der Lokalisierung

Im Anwendungscode verwendet der Code überall dort die iOS-Funktion GetLocalizedString, wo der Anzeigetext einer Benutzeroberfläche festgelegt wird (sei es der Text einer Bezeichnung oder der Platzhalter einer Eingabe usw.), um die korrekte Übersetzung für die Anzeige abzurufen:

var localizedString = NSBundle.MainBundle.GetLocalizedString ("key", "optional");
someControl.Text = localizedString;

Lokalisieren von Storyboard-Benutzeroberflächen

Das Beispiel Tasky (lokalisiertes Storyboard) zeigt, wie Text auf Steuerelementen in einem Storyboard lokalisiert wird.

Projektstruktur

Das Verzeichnis Base.lproj enthält das Storyboard und sollte auch alle Bilder enthalten, die in der Anwendung verwendet werden.

Die anderen Sprachverzeichnisse enthalten eine Datei Localizable.strings für alle Zeichenfolgenressourcen, auf die im Code verwiesen wird, sowie eine Datei MainStoryboard.strings, die Übersetzungen für Text im Storyboard enthält.

Screenshot shows the resources tree for a sample including the location of MainStoryboard strings.

Die Sprachverzeichnisse sollten eine Kopie aller Bilder enthalten, die lokalisiert wurden, um das in Base.lproj vorhandene Bild zu überschreiben.

Objekt-ID/Lokalisierungs-ID

Wenn Sie Steuerelemente in einem Storyboard erstellen und bearbeiten, wählen Sie jedes Steuerelement aus, und überprüfen Sie die für die Lokalisierung zu verwendende ID:

  • In Visual Studio für Mac befindet sie sich im Eigenschaftenpad und wird als Lokalisierungs-ID bezeichnet.
  • In Xcode wird sie als Objekt-ID bezeichnet.

Dieser Zeichenfolgenwert weist häufig eine Form wie „NF3-h8-xmR“ auf, wie im folgenden Screenshot gezeigt:

Xcode view of Storyboard localization

Dieser Wert wird in der .strings-Datei verwendet, um jedem Steuerelement automatisch übersetzten Text zuzuweisen.

MainStoryboard.strings

Das Format der Übersetzungsdatei des Storyboards ähnelt der Datei Localizable.strings, mit der Ausnahme, dass der Schlüssel (der Wert auf der linken Seite) nicht benutzerdefiniert sein kann, sondern stattdessen ein sehr spezifisches Format ObjectID.property aufweisen muss.

Im Beispiel Mainstoryboard.strings unten sehen Sie, dass alle UITextField eine placeholder-Texteigenschaft aufweisen, die lokalisiert werden kann. Alle UILabel verfügen über eine text-Eigenschaft, und der Standardtext aller UIButton wird mit normalTitle festgelegt:

"SXg-TT-IwM.placeholder" = "nombre de la tarea";
"Pqa-aa-ury.placeholder"= "otra información de tarea";
"zwR-D9-hM1.text" = "Detalles de la tarea";
"bAM-2j-Rzw.text" = "Notas";           /* Notes */
"NF3-h8-xmR.text" = "Completo";        /* Done */
"MWt-Ya-pMf.normalTitle" = "Guardar";  /* Save */
"IGr-pR-05L.normalTitle" = "Eliminar"; /* Delete */

Wichtig

Die Verwendung eines Storyboards mit Größenklassen kann zu Übersetzungen führen, die nicht in der Anwendung angezeigt werden. Die Xcode-Versionshinweise von Apple weisen darauf hin, dass ein Storyboard oder XIB nicht ordnungsgemäß lokalisiert wird, wenn drei Dinge zutreffen: Es verwendet Größenklassen, die Basislokalisierung und das Buildziel sind auf „Universell“ festgelegt, und der Build betrifft iOS 7.0. Der Fix besteht darin, die Zeichenfolgedatei Ihres Storyboards in zwei identische Dateien zu duplizieren: MainStoryboard~iphone.strings und MainStoryboard~ipad.strings, wie im folgenden Screenshot gezeigt:

Strings files

App Store-Eintrag

Folgt den FAQ von Apple zur App Store-Lokalisierung, um Übersetzungen für jedes Land einzugeben, in dem Ihre App zum Verkauf steht. Beachten Sie ihre Warnung, dass die Übersetzungen nur angezeigt werden, wenn Ihre App auch ein lokalisiertes .lproj-Verzeichnis für die Sprache enthält.

Zusammenfassung

In diesem Artikel werden die Grundlagen der Lokalisierung von iOS-Anwendungen mithilfe der integrierten Features für Ressourcenbehandlung und Storyboard behandelt.

In diesem plattformübergreifenden Leitfaden erfahren Sie mehr über i18n und L10n für iOS-, Android- und plattformübergreifende Apps (einschließlich Xamarin.Forms).