SlideShare a Scribd company logo
1 of 115
Download to read offline
Localizing Mobile Apps
Daniel Schneller, CenterDevice GmbH
Agenda
I18N vs. L10N
Languages and Regions
Text
Date and Time
Numbers
Images and other Resources
https://github.com/dschneller/I18N-Example
I18N vs. L10N
I18N
L10N
I — 18 Characters — N
L-10 Characters-N
Internationalization
I — 18 Characters — N
Localization
L-10 Characters-N
Internationalization
Internationalization
[…] process of designing a software application so that it
can potentially be adapted to various languages and
regions without engineering changes. […]*
* Wikipedia
Localization
Localization
[…] the process of adapting internationalized software for
a specific region or language by adding locale-specific
components and translating text. […]*
* Wikipedia
I18N L10NApp
Localized

App
!"#$%&!
! 🌐 🌐 !"#
$%&
Languages and Regions
Languages and Regions
Language ≠ Region
12h time used by an American living in Germany
„Jänner“ – „Januar“ [German in Austria vs. in Germany for January]
Localization ≠ Locale
German user might prefer English user interface texts
But: 24h time display
Languages and Regions
Languages and Regions
Languages and Regions
Languages and Regions
Scheme Launch Arguments
-AppleLanguages (ar,de,fr)
Order determines preference
-AppleLocale en_US
NSLocale
Encapsulates Region Settings
+ (id)autoupdatingCurrentLocale

+ (id)currentLocale
NSCurrentLocaleDidChangeNotification
[[NSNotificationCenter defaultCenter]

addObserver:self

selector:@selector(localeDidChange:)

name:NSCurrentLocaleDidChangeNotification

object:nil]
Refresh formatters, caches NSLocale instances
Refresh screen content
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
Does not contain the current language!
Locale ≠ Localization
[NSBundle mainBundle].localizations; // NSArray, (all)
[NSBundle mainBundle].preferredLocalizations[0]; // (current)
Caveats
Localizations of InfoPlist.strings determine content of „localizations“
Intersected with user’s region preferences in Settings.app
AppleLanguages launch parameter
Text
Text ≠ Text
Language of messages, buttons, labels etc.
Writing direction & alignment
Writing systems (Latin, Hebrew, Arabic…)
Numbers in text
Names & addresses
Phrases, idioms and terminology
Plurals
Sorting
…
Text ≠ Text
Language of messages, buttons, labels etc.
Writing direction & alignment
Writing systems (Latin, Hebrew, Arabic…)
Numbers in text
Names & addresses
Phrases, idioms and terminology
Plurals
Sorting
…
Base Localization
Base Localization
One leading (base)
language
Base Localization
One leading (base)
language
Add Localization
Base Localization
One leading (base)
language
Add Localization
Base Localization
One leading (base)
language
Add Localization
“.strings”files
Base Localization
One leading (base)
language
Add Localization
“.strings”files
genstrings
Base Localization
One leading (base)
language
Add Localization
“.strings”files
genstrings
ibtool
Base Localization
One leading (base)
language
Add Localization
“.strings”files
genstrings
ibtool
One copy per language
Base Localization
One leading (base)
language
Add Localization
“.strings”files
genstrings
ibtool
One copy per language
“.lproj”Ordner
Base Localization
Eine Leitsprache (Base)
“.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
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
Preview in Assistant Editor
Xcode 6: Pick Language
Double-Length Pseudo-
Language
Auto Layout
NSLocalizedString
Family of macros
NSLocalizedString

NSLocalizedStringFromTable

NSLocalizedStringFromTableInBundle

NSLocalizedStringWithDefaultValue
Access “.strings”files
Utilize NSBundle
-[[NSBundle mainBundle] localizedStringForKey:value:table:]
NSLocalizedString
Example
[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?
.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
Do not normalize text
Do not normalize text
DRY! — Do Repeat Yourself
[NSString stringWithFormat:@”…”]
Do not normalize text
DRY! — Do Repeat Yourself
[NSString stringWithFormat:@”…”]
Localizable.strings
“count” = “Anzahl”
“game” = “Spiel”
“reset” = “zurücksetzen”
“save” = “sparen”
“thumbnail” = “Daumennagel”
Do not normalize text
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”
…
Do not normalize text
Do not normalize text
Context and grammar are lost
Do not normalize text
Context and grammar are lost
Structure of sentences
Do not normalize text
Context and grammar are lost
Structure of sentences
Declination & conjugation …
Do not normalize text
Context and grammar are lost
Structure of sentences
Declination & conjugation …
Use dedicated strings per use case
Do not normalize text
Context and grammar are lost
Structure of sentences
Declination & conjugation …
Use dedicated strings per use case
“reset.counter.button” = “Auf 0 stellen”
Do not normalize text
Context and grammar are lost
Structure of sentences
Declination & conjugation …
Use dedicated strings per use case
“reset.counter.button” = “Auf 0 stellen”
Context for translators
Do not normalize text
Context and grammar are lost
Structure of sentences
Declination & conjugation …
Use dedicated strings per use case
“reset.counter.button” = “Auf 0 stellen”
Context for translators
Use self explanatory keys
Do not normalize text
Context and grammar are lost
Structure of sentences
Declination & conjugation …
Use dedicated strings per use case
“reset.counter.button” = “Auf 0 stellen”
Context for translators
Use self explanatory keys
Provide useful comments (button vs. label, approx. length, etc.)
Variables
Parameters
[NSString stringWithFormat:

NSLocalizedString(@"click.counter.label",

@"P1: Current Click Count."),

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

"click.counter.label" = "%1d x geklickt”;
Variables
Document parameter order!
“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”;
Special cases: 0 and 1
Plurals
Englisch German
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”
If-else-clause in the code: Problem solved.
Englisch Deutsch
0 No books Keine Bücher
1 1 book 1 Buch
Vielleicht nicht ganz…
Plural
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
0
1
2
wenige
viele
sonstiges
Englisch
No books
1 book
2 books
3 books
11 books
100 books
German
Keine Bücher
1 Buch
2 Bücher
3 Bücher
11 Bücher
100 Bücher
Or is it…?
Plural
0
1
2
wenige
viele
sonstiges
Englisch
No books
1 book
2 books
3 books
11 books
100 books
German
Keine Bücher
1 Buch
2 Bücher
3 Bücher
11 Bücher
100 Bücher
Arabic
‫كتاب‬ ٠
‫كتاب‬
‫كتابان‬
‫كتب‬ ٣
‫ا‬ً‫ب‬‫كتا‬ ١١
‫كتاب‬ ١٠٠
Or is it…?
Plural
.strings + .stringsdict
* http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
.strings + .stringsdict
Available since iOS7
* http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
.strings + .stringsdict
Available since iOS7
Implements (Unicode*) localization rules for
Plural
Gender [rdar://16670931]
* http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
.strings + .stringsdict
Available since iOS7
Implements (Unicode*) localization rules for
Plural
Gender [rdar://16670931]
Plist Format
Name must match .strings
.strings must exist, but may be empty
* 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
Categories per language according to Unicode
iOS additionally supports„zero“ category for all languages
Others, e. g.„few“, depend on language
String Tables
Localizable.strings
Default used by NSLocalizedString()
Big projects — big file
Can be split
NSLocalizedStringFromTable(“MyController”,“Key”,“Comment”)
MyController.strings
Project structure — Context for translators
3rd party code
Also works for .stringsdict
Date and Time
Date and Time NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
German / Germany Englisch / USA
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
German / Germany Englisch / USA
Short 08.07.14 22:32 7/8/14,10:32 PM
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
German / Germany 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
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
German / Germany 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
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
German / Germany 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
NSDateFormatter
Date and Time
Transforms between NSDate and NSString
+[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]

-[NSDateFormatter setLocale:]
NSDateFormatterStyle
German / Germany 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
Date and Time
NSDateFormatter.h
typedef enum {

NSDateFormatterNoStyle = …,

NSDateFormatterShortStyle = …,

NSDateFormatterMediumStyle = …,

NSDateFormatterLongStyle = …,

NSDateFormatterFullStyle = …

} NSDateFormatterStyle
Combine for date and time portions
NSDateFormatterNoStyle — only date / time
Get updated with the OS
NSDateFormatter
Date and Time NSDateFormatter
* http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
Date and Time
What if defaults are not suitable?
NSDateFormatter
* http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
Date and Time
What if defaults are not suitable?
Do not use hard coded format strings!
NSDateFormatter
* http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
Date and Time
What if defaults are not suitable?
Do not use hard coded format strings!
Unicode Locale Data Markup Language*
NSDateFormatter
* http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
Date and Time
What if defaults are not suitable?
Do not use hard coded format strings!
Unicode Locale Data Markup Language*
[f setDateFormat:[NSDateFormatter

dateFormatFromTemplate:@"u QQ" 

options:0

locale:LOCALE_EN_US]];



NSLog(@“%@", [f stringFromDate:july8th);
NSDateFormatter
* http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
Date and Time
What if defaults are not suitable?
Do not use hard coded format strings!
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 formatting
[formatter setDoesRelativeDateFormatting:YES];



NSLog(@“%@, %@, %@…", [formatter stringFromDate:GESTERN],

[formatter stringFromDate:HEUTE],

[formatter stringFromDate:MORGEN]);

Gestern, Heute, Morgen… [de_DE]
Yesterday, Today, Tomorrow… [en_US]
Yesterday, Today, Tomorrow…
NSDateComponentsFormatter
Formats durations
[f stringFromTimeInterval:1234.0]) // seconds
About 20 minutes remaining
NSDateIntervalFormatter
Formats time intervals
[f stringFromDate:NOW toDate:LATER])
09.07.14 12:10-13:13
Coming up next: iOS8
Numbers
Numbers
Numbers
“Plain”Numbers
Numbers
MassDistance
LengthCurrency
Percentage
Data Volume
WeightEnergy
Spelled Out
“Plain”Numbers
Numbers
Decimal separators
Grouping characters
Currency symbols
…
"
NSNumberFormatter
API similar to NSDateFormatter
Numbers NSNumberFormatter
German / Germany English / 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
Numbers
NSNumberFormatter.h
enum {

NSNumberFormatterNoStyle = …,

NSNumberFormatterDecimalStyle = …,

NSNumberFormatterCurrencyStyle = …,

NSNumberFormatterPercentStyle = …,

NSNumberFormatterScientificStyle = …,

NSNumberFormatterSpellOutStyle = …

}

typedef NSUInteger NSNumberFormatterStyle
Numbers NSNumberFormatter
Numbers
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)]);
NSNumberFormatter
Numbers
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
Numbers
Many more customization options
maximumFractionDigits
usesSignificantDigits
minimum/maximumSignificantDigits
paddingCharacter
roundingMode, roundingIncrement
…
NSNumberFormatter
Data Volume
NSByteCountFormatter
File size, amount of memory
Picks suitable unit automatically
Non-numeric display
Allow Non-Numeric Zero KB
File 1,234.57 GB
Memory 1,149.78 GB
Coming up next: iOS8
NSEnergyFormatter
Energy in joule, calories etc.
NSLengthFormatter
Distance, in miles, kilometers etc.
NSMassFormatter
Mass and weight in pounds, kg etc.
Images and other
Resources
Images
Buttons
UI Elements
UI Elements
-[UIImage imageNamed:@"myImage"];
Put image files into .lproj folders
Does not work for asset catalogues
Launch Image
Disable asset catalogue
Launch images in .lproj folders
Follows usual naming conventions for
Retina
Orientation
iPhone vs. iPad
Other Ressources
Same as images
Lookup via
-[[NSBundle mainBundle] pathForResource:ofType:]
Use cases
HTML
Text files
App Name
Info.plist
Application has localized Display Name
<key>LSHasLocalizedDisplayName</key>

<true />
InfoPlist.strings
"CFBundleDisplayName" = "国际范例";
Wrap up
Cover the Basics
Locale based formatting
NSDateFormatter
NSNumberFormatter
NSByteCountFormatter
Careful and diligent translation
Remember resources besides the source code
Next Steps
Images resources
Launch Images (if relevant)
Addresses, names
Right-to-left support
Location based pre-selection of units (miles, km etc.)
Pre-selection for pickers, options etc.
Color scheme
…
Summary
Initialer effort can be significant
Full translation
Code refactoring
Create workflows and pick tools
Ongoing maintenance rather easy
Consider relevance of individual measures for your
audience
Merci!
Hvala!
Vielen Dank! Thank You!
Grazie!
Questions?
Daniel Schneller — @dschneller 

daniel.schneller@centerdevice.com

More Related Content

Similar to Localizing Mobile Apps

2015 bioinformatics python_strings_wim_vancriekinge
2015 bioinformatics python_strings_wim_vancriekinge2015 bioinformatics python_strings_wim_vancriekinge
2015 bioinformatics python_strings_wim_vancriekingeProf. Wim Van Criekinge
 
Internationalizing Your Apps
Internationalizing Your AppsInternationalizing Your Apps
Internationalizing Your AppsJohn Wilker
 
What we can learn from Rebol?
What we can learn from Rebol?What we can learn from Rebol?
What we can learn from Rebol?lichtkind
 
Make GUI Apps with Shoes
Make GUI Apps with ShoesMake GUI Apps with Shoes
Make GUI Apps with ShoesBrian Hogan
 
Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...
Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...
Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...Andrea Telatin
 
Beginning iOS App Localization
Beginning iOS App LocalizationBeginning iOS App Localization
Beginning iOS App Localizationbigsprocket
 
I18nize Scala programs à la gettext
I18nize Scala programs à la gettextI18nize Scala programs à la gettext
I18nize Scala programs à la gettextNgoc Dao
 
Dealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginnersDealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginnersElaine Naomi
 
Ui testing on multi lingual
Ui testing on multi lingualUi testing on multi lingual
Ui testing on multi lingualtharayadav
 
Linux: Beyond ls and cd
Linux: Beyond ls and cdLinux: Beyond ls and cd
Linux: Beyond ls and cdjacko91
 
The Ring programming language version 1.5.1 book - Part 38 of 180
The Ring programming language version 1.5.1 book - Part 38 of 180The Ring programming language version 1.5.1 book - Part 38 of 180
The Ring programming language version 1.5.1 book - Part 38 of 180Mahmoud Samir Fayed
 
Enriching the semantic web tutorial session 1
Enriching the semantic web tutorial session 1Enriching the semantic web tutorial session 1
Enriching the semantic web tutorial session 1Tobias Wunner
 
Was können wir von Rebol lernen?
Was können wir von Rebol lernen?Was können wir von Rebol lernen?
Was können wir von Rebol lernen?lichtkind
 
Perl6 for-beginners
Perl6 for-beginnersPerl6 for-beginners
Perl6 for-beginnersJens Rehsack
 

Similar to Localizing Mobile Apps (20)

2015 bioinformatics python_strings_wim_vancriekinge
2015 bioinformatics python_strings_wim_vancriekinge2015 bioinformatics python_strings_wim_vancriekinge
2015 bioinformatics python_strings_wim_vancriekinge
 
Internationalizing Your Apps
Internationalizing Your AppsInternationalizing Your Apps
Internationalizing Your Apps
 
What we can learn from Rebol?
What we can learn from Rebol?What we can learn from Rebol?
What we can learn from Rebol?
 
First steps in C-Shell
First steps in C-ShellFirst steps in C-Shell
First steps in C-Shell
 
Make GUI Apps with Shoes
Make GUI Apps with ShoesMake GUI Apps with Shoes
Make GUI Apps with Shoes
 
Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...
Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...
Bioinformatica: Esercizi su Perl, espressioni regolari e altre amenità (BMR G...
 
Beginning iOS App Localization
Beginning iOS App LocalizationBeginning iOS App Localization
Beginning iOS App Localization
 
Perl bhargav
Perl bhargavPerl bhargav
Perl bhargav
 
What is a shell script
What is a shell scriptWhat is a shell script
What is a shell script
 
I18nize Scala programs à la gettext
I18nize Scala programs à la gettextI18nize Scala programs à la gettext
I18nize Scala programs à la gettext
 
Multilingual drupal 7
Multilingual drupal 7Multilingual drupal 7
Multilingual drupal 7
 
Dealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginnersDealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginners
 
Ui testing on multi lingual
Ui testing on multi lingualUi testing on multi lingual
Ui testing on multi lingual
 
Linux: Beyond ls and cd
Linux: Beyond ls and cdLinux: Beyond ls and cd
Linux: Beyond ls and cd
 
python.pdf
python.pdfpython.pdf
python.pdf
 
The Ring programming language version 1.5.1 book - Part 38 of 180
The Ring programming language version 1.5.1 book - Part 38 of 180The Ring programming language version 1.5.1 book - Part 38 of 180
The Ring programming language version 1.5.1 book - Part 38 of 180
 
Ijet Talk
Ijet TalkIjet Talk
Ijet Talk
 
Enriching the semantic web tutorial session 1
Enriching the semantic web tutorial session 1Enriching the semantic web tutorial session 1
Enriching the semantic web tutorial session 1
 
Was können wir von Rebol lernen?
Was können wir von Rebol lernen?Was können wir von Rebol lernen?
Was können wir von Rebol lernen?
 
Perl6 for-beginners
Perl6 for-beginnersPerl6 for-beginners
Perl6 for-beginners
 

Recently uploaded

Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 

Recently uploaded (20)

Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 

Localizing Mobile Apps

  • 2. Agenda I18N vs. L10N Languages and Regions Text Date and Time Numbers Images and other Resources https://github.com/dschneller/I18N-Example
  • 5. I — 18 Characters — N L-10 Characters-N
  • 6. Internationalization I — 18 Characters — N Localization L-10 Characters-N
  • 8. Internationalization […] process of designing a software application so that it can potentially be adapted to various languages and regions without engineering changes. […]* * Wikipedia
  • 10. Localization […] the process of adapting internationalized software for a specific region or language by adding locale-specific components and translating text. […]* * Wikipedia
  • 11.
  • 14. Languages and Regions Language ≠ Region 12h time used by an American living in Germany „Jänner“ – „Januar“ [German in Austria vs. in Germany for January] Localization ≠ Locale German user might prefer English user interface texts But: 24h time display
  • 18. Languages and Regions Scheme Launch Arguments -AppleLanguages (ar,de,fr) Order determines preference -AppleLocale en_US
  • 19. NSLocale Encapsulates Region Settings + (id)autoupdatingCurrentLocale
 + (id)currentLocale NSCurrentLocaleDidChangeNotification [[NSNotificationCenter defaultCenter]
 addObserver:self
 selector:@selector(localeDidChange:)
 name:NSCurrentLocaleDidChangeNotification
 object:nil] Refresh formatters, caches NSLocale instances Refresh screen content
  • 20. 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
  • 21. NSLocale Does not contain the current language! Locale ≠ Localization [NSBundle mainBundle].localizations; // NSArray, (all) [NSBundle mainBundle].preferredLocalizations[0]; // (current) Caveats Localizations of InfoPlist.strings determine content of „localizations“ Intersected with user’s region preferences in Settings.app AppleLanguages launch parameter
  • 22. Text
  • 23.
  • 24.
  • 25. Text ≠ Text Language of messages, buttons, labels etc. Writing direction & alignment Writing systems (Latin, Hebrew, Arabic…) Numbers in text Names & addresses Phrases, idioms and terminology Plurals Sorting …
  • 26. Text ≠ Text Language of messages, buttons, labels etc. Writing direction & alignment Writing systems (Latin, Hebrew, Arabic…) Numbers in text Names & addresses Phrases, idioms and terminology Plurals Sorting …
  • 28. Base Localization One leading (base) language
  • 29. Base Localization One leading (base) language Add Localization
  • 30. Base Localization One leading (base) language Add Localization
  • 31. Base Localization One leading (base) language Add Localization “.strings”files
  • 32. Base Localization One leading (base) language Add Localization “.strings”files genstrings
  • 33. Base Localization One leading (base) language Add Localization “.strings”files genstrings ibtool
  • 34. Base Localization One leading (base) language Add Localization “.strings”files genstrings ibtool One copy per language
  • 35. Base Localization One leading (base) language Add Localization “.strings”files genstrings ibtool One copy per language “.lproj”Ordner
  • 36. Base Localization Eine Leitsprache (Base) “.strings”Files genstrings ibtool Eine Kopie pro Sprache “.lproj”Ordner
  • 37. Base Localization Eine Leitsprache (Base) “.strings”Files genstrings ibtool Eine Kopie pro Sprache “.lproj”Ordner
  • 38. Base Localization Eine Leitsprache (Base) “.strings”Files genstrings ibtool Eine Kopie pro Sprache “.lproj”Ordner
  • 39. 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"; …
  • 40. Base Localization Preview in Assistant Editor Xcode 6: Pick Language Double-Length Pseudo- Language Auto Layout
  • 42. NSLocalizedString Example [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";
  • 44. .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
  • 46. Do not normalize text DRY! — Do Repeat Yourself [NSString stringWithFormat:@”…”]
  • 47. Do not normalize text DRY! — Do Repeat Yourself [NSString stringWithFormat:@”…”] Localizable.strings “count” = “Anzahl” “game” = “Spiel” “reset” = “zurücksetzen” “save” = “sparen” “thumbnail” = “Daumennagel”
  • 48. Do not normalize text 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” …
  • 50. Do not normalize text Context and grammar are lost
  • 51. Do not normalize text Context and grammar are lost Structure of sentences
  • 52. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation …
  • 53. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation … Use dedicated strings per use case
  • 54. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation … Use dedicated strings per use case “reset.counter.button” = “Auf 0 stellen”
  • 55. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation … Use dedicated strings per use case “reset.counter.button” = “Auf 0 stellen” Context for translators
  • 56. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation … Use dedicated strings per use case “reset.counter.button” = “Auf 0 stellen” Context for translators Use self explanatory keys
  • 57. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation … Use dedicated strings per use case “reset.counter.button” = “Auf 0 stellen” Context for translators Use self explanatory keys Provide useful comments (button vs. label, approx. length, etc.)
  • 58. Variables Parameters [NSString stringWithFormat:
 NSLocalizedString(@"click.counter.label",
 @"P1: Current Click Count."),
 self.clickCount] " /* P1: Current Click Count. */
 "click.counter.label" = "%1d x geklickt”;
  • 59. Variables Document parameter order! “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”;
  • 60. Special cases: 0 and 1 Plurals Englisch German 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” If-else-clause in the code: Problem solved.
  • 61. Englisch Deutsch 0 No books Keine Bücher 1 1 book 1 Buch Vielleicht nicht ganz… Plural
  • 62. 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
  • 63. 0 1 2 wenige viele sonstiges Englisch No books 1 book 2 books 3 books 11 books 100 books German Keine Bücher 1 Buch 2 Bücher 3 Bücher 11 Bücher 100 Bücher Or is it…? Plural
  • 64. 0 1 2 wenige viele sonstiges Englisch No books 1 book 2 books 3 books 11 books 100 books German Keine Bücher 1 Buch 2 Bücher 3 Bücher 11 Bücher 100 Bücher Arabic ‫كتاب‬ ٠ ‫كتاب‬ ‫كتابان‬ ‫كتب‬ ٣ ‫ا‬ً‫ب‬‫كتا‬ ١١ ‫كتاب‬ ١٠٠ Or is it…? Plural
  • 65. .strings + .stringsdict * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
  • 66. .strings + .stringsdict Available since iOS7 * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
  • 67. .strings + .stringsdict Available since iOS7 Implements (Unicode*) localization rules for Plural Gender [rdar://16670931] * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
  • 68. .strings + .stringsdict Available since iOS7 Implements (Unicode*) localization rules for Plural Gender [rdar://16670931] Plist Format Name must match .strings .strings must exist, but may be empty * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar
  • 69. .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>
  • 70. .stringsdict Categories per language according to Unicode iOS additionally supports„zero“ category for all languages Others, e. g.„few“, depend on language
  • 71. String Tables Localizable.strings Default used by NSLocalizedString() Big projects — big file Can be split NSLocalizedStringFromTable(“MyController”,“Key”,“Comment”) MyController.strings Project structure — Context for translators 3rd party code Also works for .stringsdict
  • 73. Date and Time NSDateFormatter
  • 74. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatter
  • 75. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle NSDateFormatter
  • 76. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle German / Germany Englisch / USA NSDateFormatter
  • 77. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle German / Germany Englisch / USA Short 08.07.14 22:32 7/8/14,10:32 PM NSDateFormatter
  • 78. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle German / Germany 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 NSDateFormatter
  • 79. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle German / Germany 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 NSDateFormatter
  • 80. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle German / Germany 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 NSDateFormatter
  • 81. Date and Time Transforms between NSDate and NSString +[NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:]
 -[NSDateFormatter setLocale:] NSDateFormatterStyle German / Germany 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
  • 82. Date and Time NSDateFormatter.h typedef enum {
 NSDateFormatterNoStyle = …,
 NSDateFormatterShortStyle = …,
 NSDateFormatterMediumStyle = …,
 NSDateFormatterLongStyle = …,
 NSDateFormatterFullStyle = …
 } NSDateFormatterStyle Combine for date and time portions NSDateFormatterNoStyle — only date / time Get updated with the OS NSDateFormatter
  • 83. Date and Time NSDateFormatter * http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
  • 84. Date and Time What if defaults are not suitable? NSDateFormatter * http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
  • 85. Date and Time What if defaults are not suitable? Do not use hard coded format strings! NSDateFormatter * http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
  • 86. Date and Time What if defaults are not suitable? Do not use hard coded format strings! Unicode Locale Data Markup Language* NSDateFormatter * http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
  • 87. Date and Time What if defaults are not suitable? Do not use hard coded format strings! Unicode Locale Data Markup Language* [f setDateFormat:[NSDateFormatter
 dateFormatFromTemplate:@"u QQ" 
 options:0
 locale:LOCALE_EN_US]];
 
 NSLog(@“%@", [f stringFromDate:july8th); NSDateFormatter * http://www.unicode.org/reports/tr35/tr35-dates.html#Contents
  • 88. Date and Time What if defaults are not suitable? Do not use hard coded format strings! 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
  • 89. Relative formatting [formatter setDoesRelativeDateFormatting:YES];
 
 NSLog(@“%@, %@, %@…", [formatter stringFromDate:GESTERN],
 [formatter stringFromDate:HEUTE],
 [formatter stringFromDate:MORGEN]);
 Gestern, Heute, Morgen… [de_DE] Yesterday, Today, Tomorrow… [en_US] Yesterday, Today, Tomorrow…
  • 90. NSDateComponentsFormatter Formats durations [f stringFromTimeInterval:1234.0]) // seconds About 20 minutes remaining NSDateIntervalFormatter Formats time intervals [f stringFromDate:NOW toDate:LATER]) 09.07.14 12:10-13:13 Coming up next: iOS8
  • 95. Numbers Decimal separators Grouping characters Currency symbols … " NSNumberFormatter API similar to NSDateFormatter
  • 96. Numbers NSNumberFormatter German / Germany English / 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
  • 97. Numbers NSNumberFormatter.h enum {
 NSNumberFormatterNoStyle = …,
 NSNumberFormatterDecimalStyle = …,
 NSNumberFormatterCurrencyStyle = …,
 NSNumberFormatterPercentStyle = …,
 NSNumberFormatterScientificStyle = …,
 NSNumberFormatterSpellOutStyle = …
 }
 typedef NSUInteger NSNumberFormatterStyle
  • 99. Numbers 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)]); NSNumberFormatter
  • 100. Numbers 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
  • 101. Numbers Many more customization options maximumFractionDigits usesSignificantDigits minimum/maximumSignificantDigits paddingCharacter roundingMode, roundingIncrement … NSNumberFormatter
  • 102. Data Volume NSByteCountFormatter File size, amount of memory Picks suitable unit automatically Non-numeric display Allow Non-Numeric Zero KB File 1,234.57 GB Memory 1,149.78 GB
  • 103. Coming up next: iOS8 NSEnergyFormatter Energy in joule, calories etc. NSLengthFormatter Distance, in miles, kilometers etc. NSMassFormatter Mass and weight in pounds, kg etc.
  • 106. UI Elements -[UIImage imageNamed:@"myImage"]; Put image files into .lproj folders Does not work for asset catalogues
  • 107. Launch Image Disable asset catalogue Launch images in .lproj folders Follows usual naming conventions for Retina Orientation iPhone vs. iPad
  • 108. Other Ressources Same as images Lookup via -[[NSBundle mainBundle] pathForResource:ofType:] Use cases HTML Text files
  • 109. App Name Info.plist Application has localized Display Name <key>LSHasLocalizedDisplayName</key>
 <true /> InfoPlist.strings "CFBundleDisplayName" = "国际范例";
  • 111. Cover the Basics Locale based formatting NSDateFormatter NSNumberFormatter NSByteCountFormatter Careful and diligent translation Remember resources besides the source code
  • 112. Next Steps Images resources Launch Images (if relevant) Addresses, names Right-to-left support Location based pre-selection of units (miles, km etc.) Pre-selection for pickers, options etc. Color scheme …
  • 113. Summary Initialer effort can be significant Full translation Code refactoring Create workflows and pick tools Ongoing maintenance rather easy Consider relevance of individual measures for your audience
  • 115. Questions? Daniel Schneller — @dschneller 
 daniel.schneller@centerdevice.com