Localizing Mobile Apps

  • View
    1.305

  • Download
    0

Embed Size (px)

DESCRIPTION

English Slides for my talk originally given at Developer Week 2014 in Nuremberg, Germany. It covers internationalization and localization of mobile applications, using iOS as an example platform. I look at text, numbers, date and time, images and other resources, using correct plural forms and more. There is an example application available on GitHub: https://github.com/dschneller/I18N-Example

Transcript

  • 1. Localizing MobileApps Daniel Schneller, CenterDevice GmbH

2. Agenda I18N vs. L10N Languages and Regions Text Date and Time Numbers Images and other Resources https://github.com/dschneller/I18N-Example 3. I18N vs. L10N 4. I18N L10N 5. I 18 Characters N L-10 Characters-N 6. Internationalization I 18 Characters N Localization L-10 Characters-N 7. Internationalization 8. Internationalization [] process of designing a software application so that it can potentially be adapted to various languages and regions without engineering changes. []* * Wikipedia 9. Localization 10. Localization [] the process of adapting internationalized software for a specic region or language by adding locale-specic components and translating text. []* * Wikipedia 11. I18N L10NApp Localized App !"#$%&! ! !"# $%& 12. Languages and Regions 13. Languages and Regions Language Region 12h time used by an American living in Germany Jnner Januar [German in Austria vs. in Germany for January] Localization Locale German user might prefer English user interface texts But: 24h time display 14. Languages and Regions 15. Languages and Regions 16. Languages and Regions 17. Languages and Regions Scheme Launch Arguments -AppleLanguages (ar,de,fr) Order determines preference -AppleLocale en_US 18. 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 19. 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 20. 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 users region preferences in Settings.app AppleLanguages launch parameter 21. Text 22. 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 23. 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 24. Base Localization 25. Base Localization One leading (base) language 26. Base Localization One leading (base) language Add Localization 27. Base Localization One leading (base) language Add Localization 28. Base Localization One leading (base) language Add Localization .stringsfiles 29. Base Localization One leading (base) language Add Localization .stringsfiles genstrings 30. Base Localization One leading (base) language Add Localization .stringsfiles genstrings ibtool 31. Base Localization One leading (base) language Add Localization .stringsfiles genstrings ibtool One copy per language 32. Base Localization One leading (base) language Add Localization .stringsfiles genstrings ibtool One copy per language .lprojOrdner 33. Base Localization Eine Leitsprache (Base) .stringsFiles genstrings ibtool Eine Kopie pro Sprache .lprojOrdner 34. Base Localization Eine Leitsprache (Base) .stringsFiles genstrings ibtool Eine Kopie pro Sprache .lprojOrdner 35. Base Localization Eine Leitsprache (Base) .stringsFiles genstrings ibtool Eine Kopie pro Sprache .lprojOrdner 36. 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"; 37. Base Localization Preview in Assistant Editor Xcode 6: Pick Language Double-Length Pseudo- Language Auto Layout 38. NSLocalizedString Family of macros NSLocalizedString NSLocalizedStringFromTable NSLocalizedStringFromTableInBundle NSLocalizedStringWithDefaultValue Access .stringsfiles Utilize NSBundle -[[NSBundle mainBundle] localizedStringForKey:value:table:] 39. 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" = "Zurcksetzen"; 40. .strings Files Updates? 41. .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 le and copy all new string entries to ChangedNib.strings in each lproj. #fail 42. Do not normalize text 43. Do not normalize text DRY! Do Repeat Yourself [NSString stringWithFormat:@] 44. Do not normalize text DRY! Do Repeat Yourself [NSString stringWithFormat:@] Localizable.strings count = Anzahl game = Spiel reset = zurcksetzen save = sparen thumbnail = Daumennagel 45. Do not normalize text DRY! Do Repeat Yourself [NSString stringWithFormat:@] Localizable.strings count = Anzahl game = Spiel reset = zurcksetzen save = sparen thumbnail = Daumennagel reset count zurcksetzen Anzahl save game sparen Spiel 46. Do not normalize text 47. Do not normalize text Context and grammar are lost 48. Do not normalize text Context and grammar are lost Structure of sentences 49. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation 50. Do not normalize text Context and grammar are lost Structure of sentences Declination & conjugation Use dedicated strings per use case 51. 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 52. 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 53. 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 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 Context for translators Use self explanatory keys Provide useful comments (button vs. label, approx. length, etc.) 55. Variables Parameters [NSString stringWithFormat: NSLocalizedString(@"click.counter.label", @"P1: Current Click Count."), self.clickCount] " /* P1: Current Click Count. */ "click.counter.label" = "%1d x geklickt; 56. 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; 57. Special cases: 0 and 1 Plurals Englisch German 0 No books Keine Bcher 1 One book Ein Buch sonstiges 100 books 100 Bcher Localizable.strings books.0 = No Books books.1 = One Book books.n = %1d books books.0 = Keine Bcher books.1 = Ein Buch books.n = %1d Bcher If-else-clause in the code: Problem solved. 58. Englisch Deutsch 0 No books Keine Bcher 1 1 book 1 Buch Vielleicht nicht ganz Plural 59. Englisch Deutsch 0 No books Keine Bcher 1 1 book 1 Buch 2 2 books 2 Bcher wenige 3 books 3 Bcher viele 11 books 11 Bcher sonstiges 100 books 100 Bcher Vielleicht nicht ganz Plural 60. 0 1 2 wenige viele sonstiges Englisch No books 1 book 2 books 3 books 11 books 100 books German Keine Bcher 1 Buch 2 Bcher 3 Bcher 11 Bcher 100 Bcher Or is it? Plural 61. 0 1 2 wenige viele sonstiges Englisch No books 1 book 2 books 3 books 11 books 100 books German Keine Bcher 1 Buch 2 Bcher 3 Bcher 11 Bcher 100 Bcher Arabic Or is it? Plural 62. .strings + .stringsdict * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar 63. .strings + .stringsdict Available since iOS7 * http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#ar 64. .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 65. .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 66. .strings + .stringsdict https://developer.apple.com/library/ios/releasenotes/Foundation/ RN-Foundation/index.html#//apple_ref/doc/uid/TP30000742-CH2-SW56 files.selected.label.%d NSStringLocalizedFormatKey %#@num_files_are@ selected num_files_are NSStringFormatSpecTypeKey NSStringPluralRuleType NSStringFormatValueT