Download - Lokalisierung für Mobile Apps

Transcript
Page 1: Lokalisierung für Mobile Apps

Lokalisierung für Mobile AppsDaniel Schneller, CenterDevice GmbH

Page 2: Lokalisierung für Mobile Apps

AgendaI18N vs. L10N

Sprachen und Regionen

Text

Datum und Uhrzeit

Zahlen

Bilder und andere Ressourcen

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

Page 3: Lokalisierung für Mobile Apps

I18N vs. L10N

Page 4: Lokalisierung für Mobile Apps

I18N

L10N

Page 5: Lokalisierung für Mobile Apps

InternationalizationI — 18 Zeichen — N

LocalizationL - 10 Zeichen - N

Page 6: Lokalisierung für Mobile Apps

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

Page 7: Lokalisierung für Mobile Apps

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

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

* Wikipedia

Page 8: Lokalisierung für Mobile Apps

I18N L10NApp Lokalisierte App

!"#$%&!

! 🌐 🌐 !"#

$%&

Page 9: Lokalisierung für Mobile Apps

Sprachen und Regionen

Page 10: Lokalisierung für Mobile Apps

Sprachen und RegionenSprache ≠ Region

12h-Zeit für Amerikaner in Deutschland

„Jänner“ – „Januar“

Localization ≠ Locale Deutscher bevorzugt englische Anwendungstexte

Aber: 24h-Zeitformat

Page 11: Lokalisierung für Mobile Apps

Sprachen und Regionen

Page 12: Lokalisierung für Mobile Apps

Sprachen und Regionen

Page 13: Lokalisierung für Mobile Apps

Sprachen und Regionen

Page 14: Lokalisierung für Mobile Apps

Sprachen und RegionenScheme Startparameter

-AppleLanguages (ar,de,fr)

Reihenfolge bestimmt Präferenz

-AppleLocale en_US

Page 15: Lokalisierung für Mobile Apps

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

Page 16: Lokalisierung für Mobile Apps

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

Page 17: Lokalisierung für Mobile Apps

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

Page 18: Lokalisierung für Mobile Apps

Text

Page 19: Lokalisierung für Mobile Apps
Page 20: Lokalisierung für Mobile Apps

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

Page 21: Lokalisierung für Mobile Apps

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

Page 22: Lokalisierung für Mobile Apps

Base LocalizationEine Leitsprache (Base)

Add Localization

“.strings” Files genstrings

ibtool

Eine Kopie pro Sprache “.lproj” Ordner

Page 23: Lokalisierung für Mobile Apps

Base LocalizationEine Leitsprache (Base)

“.strings” Files genstrings

ibtool

Eine Kopie pro Sprache “.lproj” Ordner

Page 24: Lokalisierung für Mobile Apps

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";

Page 25: Lokalisierung für Mobile Apps

Base LocalizationVorschau im Assistant Editor

Xcode 6: Sprachwahl

Double-Length Pseudo-Language

Auto Layout

Page 26: Lokalisierung für Mobile Apps

NSLocalizedStringMakrofamilie

NSLocalizedStringNSLocalizedStringFromTableNSLocalizedStringFromTableInBundleNSLocalizedStringWithDefaultValue

Zugriff auf “.strings” Files

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

Page 27: Lokalisierung für Mobile Apps

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";

Page 28: Lokalisierung für Mobile Apps

.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

Page 29: Lokalisierung für Mobile Apps

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”

Page 30: Lokalisierung für Mobile Apps

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.)

Page 31: Lokalisierung für Mobile Apps

VariablenParameter

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

"

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

Page 32: Lokalisierung für Mobile Apps

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”;

Page 33: Lokalisierung für Mobile Apps

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.

Page 34: Lokalisierung für Mobile Apps

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

Page 35: Lokalisierung für Mobile Apps

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

Page 36: Lokalisierung für Mobile Apps

.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

Page 37: Lokalisierung für Mobile Apps

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

Page 38: Lokalisierung für Mobile Apps

.stringsdictKategorien pro Sprache per Unicode

„zero“ geht zusätzlich in iOS immer

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

Page 39: Lokalisierung für Mobile Apps

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

Page 40: Lokalisierung für Mobile Apps

Datum und Zeit

Page 41: Lokalisierung für Mobile Apps

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

Page 42: Lokalisierung für Mobile Apps

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

Page 43: Lokalisierung für Mobile Apps

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

Page 44: Lokalisierung für Mobile Apps

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…

Page 45: Lokalisierung für Mobile Apps

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

Page 46: Lokalisierung für Mobile Apps

Zahlen

Page 47: Lokalisierung für Mobile Apps

Zahlen

MassenEntfernungen

LängenGeldbeträge

ProzentsätzeDatenmengen

GewichteEnergie

“in Worten”

“Einfache” Zahlen

Page 48: Lokalisierung für Mobile Apps

ZahlenDezimaltrennzeichen

Tausendergruppierung

Währungszeichen

"

NSNumberFormatter Verwendung ähnlich NSDateFormatter

Page 49: Lokalisierung für Mobile Apps

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

Page 50: Lokalisierung für Mobile Apps

ZahlenNSNumberFormatter.h

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

Page 51: Lokalisierung für Mobile Apps

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

Page 52: Lokalisierung für Mobile Apps

ZahlenViele weitere Anpassungmöglichkeiten

maximumFractionDigits

usesSignificantDigits

minimum/maximumSignificantDigits

paddingCharacter

roundingMode, roundingIncrement

NSNumberFormatter

Page 53: Lokalisierung für Mobile Apps

DatenmengenNSByteCountFormatter

Dateigrößen, Speichermengen

Dynamische Einheiten

Nicht-numerische Darstellung

Allow Non-Numeric Zero KB

File 1,234.57 GB

Memory 1,149.78 GB

Page 54: Lokalisierung für Mobile Apps

Coming up next: iOS8NSEnergyFormatter

Energie in Joule, Kalorien etc.

NSLengthFormatter Distanzen, in Meilen, Kilometer etc.

NSMassFormatter Masse und Gewicht in Pfund, kg etc.

Page 55: Lokalisierung für Mobile Apps

Bilder u. a. Ressourcen

Page 56: Lokalisierung für Mobile Apps

BilderButtons

UI Elemente

Page 57: Lokalisierung für Mobile Apps

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

Entsprechende Bilder in .lproj Ordner

Funktioniert nicht für Asset Catalogues

Page 58: Lokalisierung für Mobile Apps

Launch ImageAsset Catalogue abschalten

Launch Images in .lproj Ordner

Typische Namenskonventionen Retina

Orientierung

Gerätetyp

Page 59: Lokalisierung für Mobile Apps

Andere RessourcenAnalog zu Bildern

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

Beispiele HTML

Textfiles

Page 60: Lokalisierung für Mobile Apps

App NameInfo.plist

Application has localized Display Name

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

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

Page 61: Lokalisierung für Mobile Apps

Zusammenfassung

Page 62: Lokalisierung für Mobile Apps

Cover the BasicsLocale basierte Formatierung

NSDateFormatter

NSNumberFormatter

NSByteCountFormatter

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

Page 63: Lokalisierung für Mobile Apps

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

Page 64: Lokalisierung für Mobile Apps

FazitInitialer Aufwand ggf. erheblich

Komplette Übersetzung

Codeanpassung

Workflow und Toolauswahl

Andauernde Pflege überschaubar

Zielgruppenrelevanz betrachten

Page 65: Lokalisierung für Mobile Apps

Merci!

Hvala!Vielen Dank!

Thank You!

Grazie!

Page 66: Lokalisierung für Mobile Apps

Fragen?

Daniel Schneller — @dschneller [email protected]