SlideShare ist ein Scribd-Unternehmen logo
Lokalisierung für
Mobile Apps
Daniel Schneller, CenterDevice GmbH
Agenda
I18N 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
Internationalization
I — 18 Zeichen — N
Localization
L - 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
Localization
Anpassung 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 Regionen
Sprache ≠ 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 Regionen
Scheme Startparameter
-AppleLanguages (ar,de,fr)
Reihenfolge bestimmt Präferenz
-AppleLocale en_US
NSLocale
Kapselt 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
NSLocale
Enthä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 ≠ Text
Sprache für Meldungen, Labels etc.
Schreibrichtung & Alignment
Schriftsysteme
Zahlen in Text
Namen & Adressen
Phrasen, Floskeln und Begriffe
Pluralbildung
Sortierung
…
Text ≠ Text
Sprache für Meldungen, Labels etc.
Schreibrichtung & Alignment
Schriftsysteme
Zahlen in Text
Namen & Adressen
Phrasen, Floskeln und Begriffe
Pluralbildung
Sortierung
…
Base Localization
Eine Leitsprache (Base)
Add Localization
“.strings”Files
genstrings
ibtool
Eine Kopie pro Sprache
“.lproj”Ordner
Base Localization
Eine 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 Localization
Vorschau im Assistant Editor
Xcode 6: Sprachwahl
Double-Length Pseudo-
Language
Auto Layout
NSLocalizedString
Makrofamilie
NSLocalizedString

NSLocalizedStringFromTable

NSLocalizedStringFromTableInBundle

NSLocalizedStringWithDefaultValue
Zugriff auf “.strings”Files
Verwendet NSBundle
-[[NSBundle mainBundle] localizedStringForKey:value:table:]
NSLocalizedString
Beispiel
[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 Files
Updates?
Use ibtool every time you update your labels and text.

In the Base.lproj folder:



ibtool ChangedNib.xib --generate-strings-
file NewStrings.strings



Open the generated output file and copy all new string
entries to ChangedNib.strings in each lproj.
#fail
Texte nicht normalisieren
DRY! — 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 normalisieren
Kontext 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.)
Variablen
Parameter
[NSString stringWithFormat:

NSLocalizedString(@"click.counter.label",

@"P1: Current Click Count."),

self.clickCount]
"
/* P1: Current Click Count. */

"click.counter.label" = "%1d x geklickt”;
Variablen
Parameterposition 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ücher
1 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ü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
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 + .stringsdict
Seit 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>
.stringsdict
Kategorien pro Sprache per Unicode
„zero“ geht zusätzlich in iOS immer
„few“ z. B. für deutsch nicht unterstützt
String Tables
Localizable.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 Zeit
Konvertierung 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 Zeit
NSDateFormatter.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 Zeit
Und 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ätze
Datenmengen
GewichteEnergie
“in Worten”
“Einfache”Zahlen
Zahlen
Dezimaltrennzeichen
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
Zahlen
NSNumberFormatter.h
enum {

NSNumberFormatterNoStyle = …,

NSNumberFormatterDecimalStyle = …,

NSNumberFormatterCurrencyStyle = …,

NSNumberFormatterPercentStyle = …,

NSNumberFormatterScientificStyle = …,

NSNumberFormatterSpellOutStyle = …

}

typedef NSUInteger NSNumberFormatterStyle
Zahlen
NSNumberFormatter* 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
Zahlen
Viele weitere Anpassungmöglichkeiten
maximumFractionDigits
usesSignificantDigits
minimum/maximumSignificantDigits
paddingCharacter
roundingMode, roundingIncrement
…
NSNumberFormatter
Datenmengen
NSByteCountFormatter
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: iOS8
NSEnergyFormatter
Energie in Joule, Kalorien etc.
NSLengthFormatter
Distanzen, in Meilen, Kilometer etc.
NSMassFormatter
Masse und Gewicht in Pfund, kg etc.
Bilder u. a. Ressourcen
Bilder
Buttons
UI Elemente
UI Elemente
-[UIImage imageNamed:@"myImage"];
Entsprechende Bilder in .lproj Ordner
Funktioniert nicht für Asset Catalogues
Launch Image
Asset Catalogue abschalten
Launch Images in .lproj Ordner
Typische Namenskonventionen
Retina
Orientierung
Gerätetyp
Andere Ressourcen
Analog zu Bildern
Lookup mittels
-[[NSBundle mainBundle] pathForResource:ofType:]
Beispiele
HTML
Textfiles
App Name
Info.plist
Application has localized Display Name
<key>LSHasLocalizedDisplayName</key>

<true />
InfoPlist.strings
"CFBundleDisplayName" = "国际范例";
Zusammenfassung
Cover the Basics
Locale basierte Formatierung
NSDateFormatter
NSNumberFormatter
NSByteCountFormatter
Sorgfältige Übersetzung
Ressourcen außerhalb des Codes nicht vergessen
Weitere Schritte
Bildressourcen
Launch Images (sofern relevant)
Adressen, Namen
Right-to-Left Support
Automatische Auswahl von Einheiten (Meilen, km etc.)
Vorbelegung für Auswahllisten etc.
Farbschemata
…
Fazit
Initialer 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

Weitere ähnliche Inhalte

Ähnlich wie Lokalisierung für Mobile Apps

Funktionales Programmieren mit Clojure
Funktionales Programmieren mit ClojureFunktionales Programmieren mit Clojure
Funktionales Programmieren mit Clojure
Dr. Christian Betz
 
Dnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbookDnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbook
Ulrich Krause
 
Dojo Und Notes
Dojo Und NotesDojo Und Notes
Dojo Und Notesdominion
 
Thread-safe .NET durch Immutables
Thread-safe .NET durch ImmutablesThread-safe .NET durch Immutables
Thread-safe .NET durch Immutables
Robin Sedlaczek
 
Professionelle InDesign-Vorlagen realisieren – Teil 1
Professionelle InDesign-Vorlagen realisieren – Teil 1Professionelle InDesign-Vorlagen realisieren – Teil 1
Professionelle InDesign-Vorlagen realisieren – Teil 1Digicomp Academy AG
 
Die freie Programmiersprache Python
Die freie Programmiersprache Python Die freie Programmiersprache Python
Die freie Programmiersprache Python
Andreas Schreiber
 
The Lotus Code Cookbook
The Lotus Code CookbookThe Lotus Code Cookbook
The Lotus Code Cookbook
Ulrich Krause
 
OSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin Grauel
OSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin GrauelOSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin Grauel
OSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin Grauel
NETWAYS
 

Ähnlich wie Lokalisierung für Mobile Apps (9)

Funktionales Programmieren mit Clojure
Funktionales Programmieren mit ClojureFunktionales Programmieren mit Clojure
Funktionales Programmieren mit Clojure
 
Dnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbookDnug35 ak-dev.071111-cookbook
Dnug35 ak-dev.071111-cookbook
 
Dojo Und Notes
Dojo Und NotesDojo Und Notes
Dojo Und Notes
 
Thread-safe .NET durch Immutables
Thread-safe .NET durch ImmutablesThread-safe .NET durch Immutables
Thread-safe .NET durch Immutables
 
Professionelle InDesign-Vorlagen realisieren – Teil 1
Professionelle InDesign-Vorlagen realisieren – Teil 1Professionelle InDesign-Vorlagen realisieren – Teil 1
Professionelle InDesign-Vorlagen realisieren – Teil 1
 
Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1
 
Die freie Programmiersprache Python
Die freie Programmiersprache Python Die freie Programmiersprache Python
Die freie Programmiersprache Python
 
The Lotus Code Cookbook
The Lotus Code CookbookThe Lotus Code Cookbook
The Lotus Code Cookbook
 
OSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin Grauel
OSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin GrauelOSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin Grauel
OSMC 2010 | Logverarbeitung mit syslog-ng - Status und Zukunft by Martin Grauel
 

Lokalisierung für Mobile Apps