Lokalisierung für Mobile Apps

Post on 12-Jul-2015

1.077 views 0 download

Transcript of Lokalisierung für Mobile Apps

Lokalisierung für Mobile AppsDaniel Schneller, CenterDevice GmbH

AgendaI18N vs. L10N

Sprachen und Regionen

Text

Datum und Uhrzeit

Zahlen

Bilder und andere Ressourcen

https://github.com/dschneller/I18N-Example

I18N vs. L10N

I18N

L10N

InternationalizationI — 18 Zeichen — N

LocalizationL - 10 Zeichen - N

Internationalization[…] ein Programm so zu gestalten, dass es leicht (ohne den Quellcode ändern zu müssen) an andere Sprachen

und Kulturen angepasst werden kann. *

* Wikipedia

LocalizationAnpassung von […] Software an die in einem […]

geographisch oder ethnisch umschriebenen Nutzungsgebiet […] vorherrschenden lokalen sprachlichen und kulturellen Gegebenheiten. *

* Wikipedia

I18N L10NApp Lokalisierte App

!"#$%&!

! 🌐 🌐 !"#

$%&

Sprachen und Regionen

Sprachen und RegionenSprache ≠ Region

12h-Zeit für Amerikaner in Deutschland

„Jänner“ – „Januar“

Localization ≠ Locale Deutscher bevorzugt englische Anwendungstexte

Aber: 24h-Zeitformat

Sprachen und Regionen

Sprachen und Regionen

Sprachen und Regionen

Sprachen und RegionenScheme Startparameter

-AppleLanguages (ar,de,fr)

Reihenfolge bestimmt Präferenz

-AppleLocale en_US

NSLocaleKapselt aktuelle Regionaleinstellungen

+ (id)autoupdatingCurrentLocale+ (id)currentLocale

NSCurrentLocaleDidChangeNotification [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localeDidChange:) name:NSCurrentLocaleDidChangeNotification object:nil]

Formatter / Locale Instanzen erneuern

Bildschirminhalte aktualisieren

NSLocale-[NSLocale objectForKey:]

NSString* NSLocaleIdentifier NSString* NSLocaleMeasurementSystem

NSString* NSLocaleLanguageCode NSString* NSLocaleDecimalSeparator

NSString* NSLocaleCountryCode NSString* NSLocaleGroupingSeparator

NSString* NSLocaleScriptCode NSString* NSLocaleCurrencySymbol

NSString* NSLocaleVariantCode NSString* NSLocaleExemplarCharacterSet

NSString* NSLocaleCurrencyCode NSString* NSLocaleCollatorIdentifier

NSString* NSLocaleCalendar NSString* NSLocaleQuotationBeginDelimiterKey

NSString* NSLocaleCollationIdentifier NSString* NSLocaleQuotationEndDelimiterKey

NSString* NSLocaleUsesMetricSystem

NSLocaleEnthält nicht die aktuelle Sprache der Anwendung!

Locale ≠ Localization [NSBundle mainBundle].localizations; // NSArray, (alle)

[NSBundle mainBundle].preferredLocalizations[0]; // (laufende)

Caveats InfoPlist.strings Lokalisierungen bestimmen „localizations“

Schnittmenge mit Nutzerpräferenz

AppleLanguages Parameter

Text

Text ≠ TextSprache für Meldungen, Labels etc. Schreibrichtung & Alignment Schriftsysteme Zahlen in Text Namen & Adressen Phrasen, Floskeln und Begriffe Pluralbildung Sortierung …

Text ≠ TextSprache für Meldungen, Labels etc. Schreibrichtung & Alignment Schriftsysteme Zahlen in Text Namen & Adressen Phrasen, Floskeln und Begriffe Pluralbildung Sortierung …

Base LocalizationEine Leitsprache (Base)

Add Localization

“.strings” Files genstrings

ibtool

Eine Kopie pro Sprache “.lproj” Ordner

Base LocalizationEine Leitsprache (Base)

“.strings” Files genstrings

ibtool

Eine Kopie pro Sprache “.lproj” Ordner

Base Localization…

/* Class = "IBUILabel"; text = "Loaded by SecondViewController"; ObjectID = "NDk-cv-Gan"; */

"NDk-cv-Gan.text" = "Loaded by SecondViewController";

"

/* Class = "IBUILabel"; text = "First View"; ObjectID = "KQZ-1w-vlD"; */

"KQZ-1w-vlD.text" = "First View";

Base LocalizationVorschau im Assistant Editor

Xcode 6: Sprachwahl

Double-Length Pseudo-Language

Auto Layout

NSLocalizedStringMakrofamilie

NSLocalizedStringNSLocalizedStringFromTableNSLocalizedStringFromTableInBundleNSLocalizedStringWithDefaultValue

Zugriff auf “.strings” Files

Verwendet NSBundle -[[NSBundle mainBundle] localizedStringForKey:value:table:]

NSLocalizedStringBeispiel

[button setTitle:NSLocalizedString(@"reset.counter.button.title", @"Reset Counter action button") forState:…];

genstrings — Localizable.strings /* Reset Counter action button */"reset.counter.button.title" = "Zurücksetzen";

.strings FilesUpdates?

Use ibtool every time you update your labels and text.In the Base.lproj folder:ibtool ChangedNib.xib --generate-strings-file NewStrings.stringsOpen the generated output file and copy all new string entries to ChangedNib.strings in each lproj.

#fail

Texte nicht normalisierenDRY! — Do Repeat Yourself

[NSString stringWithFormat:@”…”]

Localizable.strings “count” = “Anzahl”

“game” = “Spiel”

“reset” = “zurücksetzen”

“save” = “sparen”

“thumbnail” = “Daumennagel”

“reset count”

”zurücksetzen Anzahl”

“save game”

“sparen Spiel”

Texte nicht normalisierenKontext und Grammatik gehen verloren

Satzbau

Wortformen (Deklination & Konjugation) …

Eigene Strings für jeden Zweck “reset.counter.button” = “Auf 0 stellen”

Kontext für Übersetzer Sprechende Keys

Hinreichende Kommentare (Button vs. Label, ungefähre Länge etc.)

VariablenParameter

[NSString stringWithFormat: NSLocalizedString(@"click.counter.label", @"P1: Current Click Count."), self.clickCount]

"

/* P1: Current Click Count. */"click.counter.label" = "%1d x geklickt”;

VariablenParameterposition dokumentieren!

“Zeige 4 von 12 gesamt”

“Total 12 — Showing 4”

/* … Param 1: current page; Param 2: total count */"current.page.label" = “Zeige %1d von %2d gesamt”;/* … Param 1: current page; Param 2: total count */"current.page.label" = “Total %2d — Showing %1d”;

Sonderfälle 0 und 1

Plural

Englisch Deutsch

0 No books Keine Bücher1 One book Ein Buch

sonstiges 100 books 100 Bücher

Localizable.strings“books.0” = “No Books”

“books.1” = “One Book”

“books.n” = “%1d books”

“books.0” = “Keine Bücher”

“books.1” = “Ein Buch”

“books.n” = “%1d Bücher”

Abfrage im Code, Problem gelöst.

Englisch Deutsch

0 No books Keine Bücher1 1 book 1 Buch2 2 books 2 Bücher

wenige 3 books 3 Bücherviele 11 books 11 Bücher

sonstiges 100 books 100 Bücher

Vielleicht nicht ganz…

Plural

Englisch Deutsch Arabisch

0 No books Keine Bücher ٠ كتاب1 1 book 1 Buch كتاب2 2 books 2 Bücher كتابان

wenige 3 books 3 Bücher ٣ كتبviele 11 books 11 Bücher ١١ كتابًا

sonstiges 100 books 100 Bücher ١٠٠ كتاب

Vielleicht nicht ganz…

Plural

.strings + .stringsdictSeit iOS7

Implementiert (Unicode*) Lokalisierungsregeln für Plural

Geschlecht [rdar://16670931]

Plist Format Name identisch mit .strings

.strings muss existieren, kann aber leer sein

* http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar

.strings + .stringsdict

https://developer.apple.com/library/ios/releasenotes/Foundation/↩︎ RN-Foundation/index.html#//apple_ref/doc/uid/TP30000742-CH2-SW56

<dict>    <key>files.selected.label.%d</key>    <dict>        <key>NSStringLocalizedFormatKey</key> <string>%#@num_files_are@ selected</string>        <key>num_files_are</key>  <dict>            <key>NSStringFormatSpecTypeKey</key> <string>NSStringPluralRuleType</string>            <key>NSStringFormatValueTypeKey</key> <string>d</string>            <key>zero</key>    <string>No file is</string>            <key>one</key>     <string>A file is</string>            <key>other</key>   <string>%d files are</string>        </dict>    </dict></dict>

.stringsdictKategorien pro Sprache per Unicode

„zero“ geht zusätzlich in iOS immer

„few“ z. B. für deutsch nicht unterstützt

String TablesLocalizable.strings

Default für NSLocalizedString()

Große Projekte — große Datei

Optional zerlegbar NSLocalizedStringFromTable(“MyController”, “Key”, “Comment”)

MyController.strings

Projektgliederung — Kontext für Übersetzer

3rd Party Code

Analog für .stringsdict

Datum und Zeit

Datum und ZeitKonvertierung zwischen NSDate und NSString

+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:] -[NSDateFormatter setLocale:]

NSDateFormatterStyle

Deutsch / Deutschland Englisch / USA

Short 08.07.14 22:32 7/8/14,10:32 PM

Medium 08.07.2014 22:32:36 Jul 8, 2014, 10:32:36 PM

Long 8. Juli 2014 22:32:36 MESZ Jul 8, 2014, 10:32:36 PM GMT+2

Full Dienstag, 8. Juli 2014 12:32:36 Mitteleuropäische Sommerzeit

Tuesday, July 8, 2014 at 12:39:16 PM Central European Summer Time

No - -

NSDateFormatter

Datum und ZeitNSDateFormatter.h

typedef enum { NSDateFormatterNoStyle = …, NSDateFormatterShortStyle = …, NSDateFormatterMediumStyle = …, NSDateFormatterLongStyle = …, NSDateFormatterFullStyle = …} NSDateFormatterStyle

Kombinierbar für Datum und Zeit NSDateFormatterNoStyle — nur Datum / Zeit

Aktualisierung durch OS Updates

NSDateFormatter

Datum und ZeitUnd wenn die Defaults nicht reichen?

Keine konkreten Format-Strings verwenden!

Unicode Locale Data Markup Language* [f setDateFormat:[NSDateFormatter dateFormatFromTemplate:@"u QQ" options:0 locale:LOCALE_EN_US]];NSLog(@“%@", [f stringFromDate:july8th);

Q3 2014

NSDateFormatter

* http://www.unicode.org/reports/tr35/tr35-dates.html#Contents

Relative Zeitangaben [formatter setDoesRelativeDateFormatting:YES];NSLog(@“%@, %@, %@…", [formatter stringFromDate:GESTERN], [formatter stringFromDate:HEUTE], [formatter stringFromDate:MORGEN]);

Gestern, Heute, Morgen… [de_DE]

Yesterday, Today, Tomorrow… [en_US]

Gestern, Heute, Morgen…

NSDateComponentsFormatter Darstellung von Zeitdauern

[f stringFromTimeInterval:1234.0]) // seconds

About 20 minutes remaining

NSDateIntervalFormatter Darstellung von Zeiträumen

[f stringFromDate:NOW toDate:LATER])

09.07.14 12:10-13:13

Coming up next: iOS8

Zahlen

Zahlen

MassenEntfernungen

LängenGeldbeträge

ProzentsätzeDatenmengen

GewichteEnergie

“in Worten”

“Einfache” Zahlen

ZahlenDezimaltrennzeichen

Tausendergruppierung

Währungszeichen

"

NSNumberFormatter Verwendung ähnlich NSDateFormatter

Zahlen NSNumberFormatter

Deutsch / Deutschland Englisch / USA

No 1234,56 1234.56

Decimal 1.234,56 1,234.56

Currency 1.234,56 € $1,234.56

Percent 123.456% 123,456%

Scientific 1,23456E+03 1.23456E3

SpellOut eintausendzweihundertvier-unddreißig Komma fünf sechs

one thousand two hundred thirty-four point five six

ZahlenNSNumberFormatter.h

enum { NSNumberFormatterNoStyle = …, NSNumberFormatterDecimalStyle = …, NSNumberFormatterCurrencyStyle = …, NSNumberFormatterPercentStyle = …, NSNumberFormatterScientificStyle = …, NSNumberFormatterSpellOutStyle = …} typedef NSUInteger NSNumberFormatterStyle

ZahlenNSNumberFormatter* f = [[NSNumberFormatter alloc] init];f.numberStyle = NSNumberFormatterNoStyle;

f.locale = LOCALE_DE_AT; NSLog(@"NoStyle de_AT: %@", [f stringFromNumber:@(1234.56)]);

f.locale = LOCALE_EN_US; f.maximumFractionDigits = 2;NSLog(@“NoStyle en_US: %@", [f stringFromNumber:@(1234.56)]);

"

NoStyle de_AT: 1235

NoStyle en_US: 1234.56

NSNumberFormatter

ZahlenViele weitere Anpassungmöglichkeiten

maximumFractionDigits

usesSignificantDigits

minimum/maximumSignificantDigits

paddingCharacter

roundingMode, roundingIncrement

NSNumberFormatter

DatenmengenNSByteCountFormatter

Dateigrößen, Speichermengen

Dynamische Einheiten

Nicht-numerische Darstellung

Allow Non-Numeric Zero KB

File 1,234.57 GB

Memory 1,149.78 GB

Coming up next: iOS8NSEnergyFormatter

Energie in Joule, Kalorien etc.

NSLengthFormatter Distanzen, in Meilen, Kilometer etc.

NSMassFormatter Masse und Gewicht in Pfund, kg etc.

Bilder u. a. Ressourcen

BilderButtons

UI Elemente

UI Elemente-[UIImage imageNamed:@"myImage"];

Entsprechende Bilder in .lproj Ordner

Funktioniert nicht für Asset Catalogues

Launch ImageAsset Catalogue abschalten

Launch Images in .lproj Ordner

Typische Namenskonventionen Retina

Orientierung

Gerätetyp

Andere RessourcenAnalog zu Bildern

Lookup mittels -[[NSBundle mainBundle] pathForResource:ofType:]

Beispiele HTML

Textfiles

App NameInfo.plist

Application has localized Display Name

<key>LSHasLocalizedDisplayName</key><true />

InfoPlist.strings "CFBundleDisplayName" = "国际范例";

Zusammenfassung

Cover the BasicsLocale basierte Formatierung

NSDateFormatter

NSNumberFormatter

NSByteCountFormatter

Sorgfältige Übersetzung Ressourcen außerhalb des Codes nicht vergessen

Weitere SchritteBildressourcen

Launch Images (sofern relevant)

Adressen, Namen

Right-to-Left Support

Automatische Auswahl von Einheiten (Meilen, km etc.)

Vorbelegung für Auswahllisten etc.

Farbschemata

FazitInitialer Aufwand ggf. erheblich

Komplette Übersetzung

Codeanpassung

Workflow und Toolauswahl

Andauernde Pflege überschaubar

Zielgruppenrelevanz betrachten

Merci!

Hvala!Vielen Dank!

Thank You!

Grazie!

Fragen?

Daniel Schneller — @dschneller daniel.schneller@centerdevice.com