2. What We’ll Cover
• Internationalization vs Localization
• Content Types
• Text
• Dates
• Numbers
• Images
• Directionality
• Xcode Tips & Tricks
3. Why do it?
• The App Store is available in over 150 countries.
• 69% of app revenue comes from outside the U.S.
• Some users may speak English, but it may not be
their primary language.
4. Internationalization
vs
Localization
• Localization is the process of translating your app
into multiple languages.
• Internationalization is the process of making your
app able to adapt to different languages, regions,
and cultures.
6. Strings Tables
• Translated text is stored in strings tables.
• Localizable.strings
• Key value pairs
• XLIFF format
7. XLIFF
<file original="InternationalizationExample/Localizable.strings" source-language="en" datatype="plaintext"
target-language="es">
<header>
<tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="6.4" build-num="6E35b"/>
</header>
<body>
<trans-unit id="Invalid Password">
<source>Invalid Password</source>
<target>Contraseña invalida</target>
<note>Title of the alert that is displayed when the user enters an invalid password.</note>
</trans-unit>
<trans-unit id="Please enter a password.">
<source>Please enter a password.</source>
<target>Por favor, introduzca una contraseña .</target>
<note>Instructions displayed when the user enters an invalid password.</note>
</trans-unit>
</body>
</file>
XML Localisation Interchange File Format
8. NSLocalizedString
• Parameters:
• Key - The key to use in the strings table.
• Comment - Provides context for translators.
<trans-unit id="Invalid Password">
<source>Invalid Password</source>
<target>Contraseña invalida</target>
<note>Title of the alert that is displayed when the user enters
an invalid password.</note>
</trans-unit>
NSLocalizedString(“Invalid Password”, comment: “Title of the alert
that is displayed when the user enters an invalid password.”)
9. Format Strings
[NSString localizedStringWithFormat:
NSLocalizedString(@“%@ is %d meters tall”, @“Name and
height (in meters) of a mountain”), mountain.name,
mountain.height];
<source>%@ is %d meters tall</source>
<target>%1$@ is %2$d meters tall</target>
<note>Name and height (in meters) of a mountain</note>
10. NSLocalizedString and DRY
• Don’t copy and paste NSLocalizedString macros/
functions everywhere if they are textually and
semantically the same.
• Instead of creating a constant for the key, create a
constant for the localized string. Otherwise, it won’t
be included in the XLIFF file when exported.
11. This string won’t get exported:
struct Constants {
struct Localization {
static let OkButtonTitle = "Ok"
}
}
let okButtonTitle = NSLocalizedString(Constants.Localization.OkButtonTitle,
comment: "Title of button to dismiss an alert")
This string will get exported and you only write the
comment once:
struct Constants {
struct Localization {
static let OkButtonTitle = NSLocalizedString("Ok", comment: "Title of
button to dismiss an alert")
}
}
let okButtonTitle = Constants.Localization.OkButtonTitle
14. US English Aug 26, 2015
UK English Aug 26, 2015
Chinese 8⽉月 26, 2015
let df = NSDateFormatter()
df.dateFormat = “MMM d, y”
US English Aug 26, 2015
UK English 26 Aug 2015
Chinese 2015年8⽉月26⽇日
let df = NSDateFormatter()
df.dateStyle = .MediumStyle
15. Apple’s default styles don’t fit
your need?
let df = NSDateFormatter()
df.setLocalizedDateFormatFromTemplate("MMM d")
17. NSNumberFormatter
• Just like NSDateFormatter, it is locale-sensitive
• NSNumberFormatter:
• +localizedStringFromNumber:numberStyle:
• NSString:
• +localizedStringWithFormat:
US English 1,234.56
France 1 234,56
Arabic ١٬٢٣٤٫٥٦
18. Currency
When using the currency style, the currency symbol
will change as well. No currency conversion is
performed. ($5 != £5)
19. Other Units
• NSMassFormatter
• NSEnergyFormatter
• And many more…
US English 44.092 pounds
Italian 20 chilogrammi
let weight = 20.0 // Store weight in metric units
let massFormatter = NSMassFormatter()
massFormatter.unitStyle = .Long
let formatted = massFormatter.stringFromKilograms(weight)
21. Tips
• Avoid using images with text in them.
• Avoid image based puns. (🐝 Clever)
• Consider regional differences. A red octagon
symbolizes “stop” in the US, but in Japan, stop
signs are triangular.
22. Accessing Localized
Resources (iOS 9)
Don’t access the directories manually:
let lang = NSLocale.preferredLanguages().firstObject!
let lprojPath = lang.stringByAppendingPathExtension("lproj")
let filePath = NSBundle.mainBundle().pathForResource("stopSign", ofType: "png",
inDirectory: lprojPath)
NSBundle.mainBundle().imageForResource("stopSign")
NSBundle.mainBundle().pathForSoundResource("greeting")
NSBundle.mainBundle().URLForResource("help", withExtension: "pdf")
Use the NSBundle methods:
24. Directionality
• Some languages such as Arabic or Hebrew are read
from right to left.
• AutoLayout leading and trailing constraints
cause views to automatically flip.
• To prevent flipping your UI, use right and left
attributes on your constraints instead of leading
and trailing.
25. What not to flip
• Video controls and timeline indicators
• Images, unless they communicate a sense of
direction, such as arrows
• Clocks
• Music notes and sheet music
• Graphs (x– and y–axes always appear in the same
orientation)
28. Sorting
• Use the “localizedStandardCompare:” selector for
sort descriptors used on user-facing strings. This will
sort according to the language rules of the current
locale.
compare: A, Ä, B, C, a, ä, b, c
localizedCaseInsensitiveCompare: A, a, b, B, c, C, ä, Ä
localizedStandardCompare: a, A, b, B, c, C, ä, Ä