preferred language
if the app is not support the language, fall to second until the app support
new customize number system
use numberFormatter
to get it for free
In previous WWDC , localizing with xcode 6 that introduce XLIFF files that allows external translators to provide translations without developers worrying about the format.
in swift NSLocalizedString
to get simple localized strinng
String.localizaedStringWithFormat(format, args)
to get localized formatted string
String.localizedStringWithFormat(NSLocalizedString("Location: %@"), string, string)
for combination of both above
sometimes it does not makes for foreign speaker to understand our language ordering
let str = String.localizedStringWithFormat(
NSLocalizedString("copy %@’s %@",
comment: "copying item from user"),
"hairForce1", "photos")
en.lproj
"Copy %@’s %@" = "Copying %@’s %@";
//this will gives "Copying hairForce1's photos
de.lproj
"Copy %@’s %@" = "%@ von %@ kopieren";
//hairForce1 von photos kopieren
(Translation : Copy HairForce1 from photos) is not make sense
"Copy %@’s %@" = "%$2@ von %$1@ kopieren";
//This will change the ordering and becomes "photos von hairForce1 kopieren" which is "Copying hairForce1's photos"
use below for proper localized asset.
NSBundle.mainBundle().imageForResource("stopSign")
NSBundle.mainBundle().pathForSoundResource("greeting")
NSBundle.mainBundle().URLForResource("help", withExtension: "pdf")
Every language has different style for quality of one or more. Different rules becomes a issues and requires specific logics to handle. iOS provides the stringsdict file for handling this kind of problem.
Refer to Internationalization and localization Guide Appendix C stringsdict File Format
in iOS 9, we can set different strings for displaying in different device widths without using autolayout.
<key>Welcome</key>
<dict>
<key>NSStringVariableWidthRuleType</key>
<dict>
<key>20</key>
<!-- show "hi" in iPod Touch>
<string>Hi</string>
<key>25</key>
<!-- show "welcome" in iPhone>
<string>Welcome</string>
<!-- show "Welcome to the store!" in iPad>
<key>50</key>
<string>Welcome to the store!</string>
</dict>
</dict>
in English , we use "." as showing decimal places. In German, the dot is use to separate the thousands. In order to handle this,
//showing 3.142 in english and 3,142 in German
let pi = String.localizedStringWithFormat("%.3f", M_PI)
different style for showing currencies
Again, date formats of US differs from Italians.
let df = NSDateFormatter()
df.dateStyle = .ShortStyle
df.timeStyle = .ShortStyle
//this will print suitable format for different language.
print(df.stringFromDate(NSDate())
//available in iOS 8
df.setLocalizedDateFormatFromTemplate("yyyyMMddjjmmss")
for example we have to show weight of 6 pounds to Italian weight unit. We don't know the metric of Italian so we have to find out and do the convert on our own. Instead, we can use NSMassFormatter
to format the unit and the number correctly.
let weight = 20.0 // weight in metric units
let massFormatter = NSMassFormatter()
massFormatter.unitStyle = .Long
let formatted =
massFormatter.stringFromKilograms(weight)
//shows 44.092 pounds in EN-US and 20.0 in Italian
print(formatted)
NSPersonNameComponents
and NSPersonNameComponentsFormatter
are useful classes when we need to format the names properly in different languages
let components = NSPersonNameComponents()
components.givenName = "Grace"
components.middleName = "Murray"
components.familyName = "Hopper"
//Russian
let components = NSPersonNameComponents()
components.givenName = "Фёдор"
components.middleName = "Михайлович"
components.familyName = "Достоевский"
//set up the formatter
let formatter = NSPersonNameComponentsFormatter()
formatter.style = .Short
formatter.stringFromPersonNameComponents(components)
the result as follows:
when we do enumeration on string that contains emoji, this may gives unexpected result as there are multiple characters to compose the emoji.
we should this method to loop through the string
let str = "test 🍻"
str.enumerateSubstringsInRange(str.startIndex ..< str.endIndex,
options: .ByComposedCharacterSequences) {
(substring, substringRange, enclosingRange, stop) -> () in
print("\(substring)")
}
result:
Optional("t")
Optional("e")
Optional("s")
Optional("t")
Optional(" ")
Optional("🍻")
sometimes we change the cases of the string. The capped letter might not to reasonable for non-english speakers.
we should use:
let str = "istanbul"
//this will capitalized the proper letter which makes sense for the locale
print(str.localizedCapitalizedString)
//other related function..
print(str.localizedUppercaseString)
print(str.localizedLowercaseString)
special character can not be searched by other language
let str = "Über"
//this will return nil as not matching
print(str.rangeOfString("uber"))
//use below for implicitly converting u to Ü
//printing 0..<4
// available from 9.0
print(str.localizedStandRangeOfString("uber"))
//true
// available from 9.0
print(str.localizedStandardContainsString("uber"))
let transliterated = "👍".stringByApplyTransform(NSStringTransformToXMLHex, reserve: false)
// 👍
print(transliterated)
side note : do not hard code the tableViewCell height as different languages requiring diff. heights for show the text
Related session : New UIKit Support for International User Interfaces WWDC 2015