Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Felix Bartz: Successful App Localization

Realm
June 05, 2017

Felix Bartz: Successful App Localization

Realm

June 05, 2017
Tweet

More Decks by Realm

Other Decks in Programming

Transcript

  1. • Is localizing worth the effort? • Fundamentals, such as:

    work with volunteers or professionals? • How do I internationalize my app? What I am not going to talk about
  2. • Pitfall 1: Concepts • Pitfall 2: Time constraints •

    Pitfall 3: Organizational skills • Pitfall 4: Tools & Platforms What I am going to talk about
  3. The User Interface Concepts > User Interface • Provide sufficient

    space: other languages are up to 20% longer • Look for ways to shorten space-constrained strings • Custom font? Does it do special characters? What did we learn?
  4. String Design Concepts > String Design Placeholders and their pains

    /* No comment provided by engineer. */ "server_down" = "We are working on it and expect to restore service by %s."; Day of the week? am Dienstag Date? am 24.12.2014 Time? um 23:00 Uhr What could %s be?
  5. String Design Concepts > String Design Placeholders and their pains

    /* %s will be replaced by local time, e.g. 3:00 AM. */ "server_down" = "We are working on it and expect to restore service by %s."; What could %s be? ✓ /* %s e.g. 3:00 AM. */ "server_down" = "We are working on it and expect to restore service by %s."; or
  6. String Design Concepts > String Design Placeholders and their pains

    Articles in front of placeholders… "notification" = "%1$@ sent you a %2$@"; "text_message" = "text message"; "video" = "video";
  7. String Design Concepts > String Design Placeholders and their pains

    Solution? "notification" = "%1$@ sent you a %2$@"; "text_message" = "text message"; "video" = "video"; "notification" = "%1$@ sent you %2$@"; "text_message" = "a text message"; "video" = "a video"; Add articles and prepositions to the placeholder content.
  8. String Design Concepts > String Design Placeholders and their pains

    - what did we learn? • Use the comment for vital information • Communicate what type of data the placeholder represents • Just because something works in English, this does not necessarily apply to other languages
  9. String Design Concepts > String Design Multiple Use of Strings

    /* No comment provided by engineer. */ "me" = "Me"; In this chat group: Me Chat group created by: Me Gruppenteilnehmer: Ich Gruppe erstellt von: Mir
  10. String Design Concepts > String Design Use of Generic Terms

    and Phrases /* No comment provided by engineer. */ "success" = "Success"; YouTube copy link: Geschafft
  11. String Design Concepts > String Design Use of Generic Terms

    and Phrases DON’T DO THIS /* No comment provided by engineer. */ "success" = "Success"; AT LEAST ADD A COMMENT
  12. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_local_vol" = "the volume %@"; "desc_network_vol" = "the network volume %@"; "desc_folder_network_vol" = "the folder %1$@ on the network volume %2$@"; "desc_folder_local" = "the folder %1$@ on the volume %2$@"; "desc_local_vol" = "the volume %@";
  13. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_local_vol" = "the volume %@"; In German?
  14. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_local_vol" = "the volume %@"; "desc_backup_everything" = ""; "desc_local_vol" = ""; "desc_local_vol" = "das Volume %@"; "desc_backup_everything" = "BBB kopiert <sourceWhole> auf <destWhole>.";
  15. BBB kopiert das Volume X auf das Volume Y. String

    Design Concatenated Strings Concepts > String Design
  16. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_network_vol" = "the network volume %@"; "desc_folder_network_vol" = "the folder %1$@ on the network volume %2$@"; "desc_folder_local" = "the folder %1$@ on the volume %2$@"; "desc_local_vol" = "the volume %@"; ✓ "desc_network_vol" = "the network volume %@"; ✓ "desc_folder_local" = "the folder %1$@ on the volume %2$@"; ?
  17. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_folder_local" = "the folder %1$@ on the volume %2$@"; "desc_backup_everything" = "BBB kopiert <sourceWhole> auf <destWhole>."; "desc_local_vol" = "the volume %@"; "desc_local_vol" = ""; "desc_local_vol" = "das Volume %@"; "desc_folder_local" = ""; "desc_folder_local" = „den Ordner %1$@ auf dem Volume %2$@";
  18. String Design Concepts > String Design Concatenated Strings BBB kopiert

    das Volume A auf den Ordner B auf dem Volume C.
  19. BBB kopiert das Volume A in den Ordner B auf

    dem Volume C. String Design Concepts > String Design Concatenated Strings String Design
  20. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_folder_network_vol" = "the folder %1$@ on the network volume %2$@"; "desc_local_vol" = "the volume %@"; ✓ "desc_network_vol" = "the network volume %@"; ✓ "desc_folder_local" = "the folder %1$@ on the volume %2$@"; ✗ ✗ "desc_folder_network_vol" = "the folder %1$@ on the network volume %2$@";
  21. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_backup_everything" = "BBB will clone <sourceWhole> to <destWhole>."; "desc_backup_everything" = "BBB will clone <sourceWhole> to <destWhole>."; Why do we fail here? "desc_local_vol" = "the volume %@"; "desc_network_vol" = "the network volume %@"; "desc_folder_local" = "the folder %1$@ on the volume %2$@"; "desc_folder_network_vol" = "the folder %1$@ on the network volume %2$@";
  22. String Design Concepts > String Design Concatenated Strings BBB will

    clone <sourceWhole> to the folder %1$@ on network volume %2$@. CCC clonerà <sourceWhole> sulla cartella %1$@ sul volume di rete %2$@. BBB will clone <sourceWhole> to the network volume %@. CCC clonerà <sourceWhole> sul volume di rete %@.
  23. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; "desc_folder_local" = "the folder %1$@ on the volume %2$@"; How do we succeed? "desc_backup_everything" = "BBB will clone <sourceWhole> to <destWhole>."; "desc_folder_local" = "the folder %1$@ on the volume %2$@"; <sourceWhole> & <destWhole> use the same pool of strings
  24. String Design Concepts > String Design Concatenated Strings Solution -

    Step 1 "desc_backup_everything" = "BBB will clone <sourceWhole> to <destWhole>."; "source_desc_folder_local" = "the folder %1$@ on the volume %2$@"; "source_desc_folder_local" = "the folder %1$@ on the volume %2$@"; "dest_desc_folder_local" = "the folder %1$@ on the volume %2$@"; "desc_backup_everything" = "BBB will clone <sourceWhole> to <destWhole>."; Separate strings pools for <sourceWhole> & <destWhole>
  25. String Design Concepts > String Design Concatenated Strings "desc_backup_everything" =

    "BBB will clone <sourceWhole> to <destWhole>."; Solution - Step 2 "desc_backup_everything" = "BBB will clone <sourceWhole> <destWhole>."; Move the preposition “to” into the ‘Destination’ string. "source_desc_folder_local" = "the folder %1$@ on the volume %2$@"; "dest_desc_folder_local" = "the folder %1$@ on the volume %2$@"; "source_desc_folder_local" = "the folder %1$@ on the volume %2$@"; "dest_desc_folder_local" = "to the folder %1$@ on the volume %2$@";
  26. String Design Concepts > String Design Concatenated Strings In German

    "desc_backup_everything" = "BBB kopiert <sourceWhole> <destWhole>."; "source_desc_folder_local" = "den Ordner %1$@ auf dem Volume %2$@"; "dest_desc_folder_local" = "in den Ordner %1$@ auf dem Volume %2$@";
  27. BBB kopiert den Ordner A auf dem Volume B in

    den Ordner C auf dem Volume D.
  28. String Design Concepts > String Design Concatenated Strings In German

    "desc_backup_everything" = "BBB kopiert <sourceWhole> <destWhole>."; "source_desc_local_vol" = "das Volume %@"; "dest_desc_local_vol" = "auf das Volume %@";
  29. String Design Concepts > String Design Concatenated Strings – what

    did we learn? • Works in one language ≠ works in other languages • Move mean little fellas such as prepositions or articles into the placeholder strings • Provide for order changes by using %1$@
  30. String Design Concepts > String Design "%tu matches found" =

    "%tu matches found"; The Plural - enemy of the state Most languages only have one plural.
  31. String Design Concepts > String Design "%tu matches found" =

    "%tu matches found"; The Plural - enemy of the state "%tu matches found" = "%tu Treffer"; "%tu matches found" = "%tu resultados"; "%tu matches found" = "%tu risultati";
  32. String Design Concepts > String Design The Plural - enemy

    of the state Unfortunately, not all languages have only one plural …
  33. String Design Concepts > String Design The Plural - enemy

    of the state Plurals in “western” languages 1 = Singular 2 – ∞ = Plural
  34. String Design Concepts > String Design The Plural - enemy

    of the state Plurals in most Asian languages 1 – ∞ = One consistent form
  35. String Design Concepts > String Design The Plural - enemy

    of the state 1 = Singular 0, 5-20, 25-30, … = Plural Form 2 1, 21, 31, 41, 51, 61, … = Singular 2, 3, 4, 22-24, … = Plural Form 1 Plurals in Russian
  36. String Design Concepts > String Design The Plural - enemy

    of the state Solution? A .stringsdict file
  37. String Design Concepts > String Design The Plural - enemy

    of the state <dict> <key>NSStringFormatSpecTypeKey</key> <string>NSStringPluralRuleType</string> <key>NSStringFormatValueTypeKey</key> <string>tu</string> <key>zero</key> <string>No matches found</string> <key>one</key> <string>%tu match found</string> <key>other</key> <string>%tu matches found</string> </dict> <dict> <key>NSStringFormatSpecTypeKey</key> <string>NSStringPluralRuleType</string> <key>NSStringFormatValueTypeKey</key> <string>tu</string> <key>zero</key> <string>Совпадений не обнаружено</string> <key>one</key> <string>%tu совпадение обнаружено</string> <key>many</key> <string>%tu совпадений обнаружено</string> <key>other</key> <string>%tu совпадения обнаружено</string> </dict> English Russian
  38. String Design Concepts > String Design The Plural – what

    did we learn? • Not every language has just one plural form • Apple offers a simple solution • Expect the unexpected!
  39. String Design Concepts > String Design Conclusion • Be aware:

    there are languages that use a different syntax • You do not need to know the syntax of every single language • If in doubt: ask someone who is good at this stuff • Important: You don’t have to be an expert. 
 But expect this to need time during the translation.
  40. Time Constraints Depends on what? • Word count of the

    resources • Possible specialization in a certain topic • Customization level and complexity of the UI • Your internationalization efforts • Thoroughness of the translators
  41. Time Constraints Depends on what? *2-3 reviews • (Typos) •

    Length constraints • Context correctness • Undiscovered issues of all sorts (gender, plurals, prepositions, order)
  42. Time Constraints Standard iPhone App: 1500 words in resources 350

    words in App Store Translation Data exchange Review Initial Localization Month M T W T F S S Do you see the issue?
  43. Time Constraints Standard Update: 200 words in resources 70 words

    release notes Translation Data exchange Review Update Localization Month M T W T F S S
  44. Time Constraints Ecosystem biorhythm Value Axis 0 12.5 25 37.5

    50 Category Axis Jan Feb Mar Apr May June Juy Aug Sep Oct Nov Dec Calendar year Workload Pre-WWDC Pre-iTC Xmas shutdown OS releases
  45. Time Constraints Conclusion • Very often the main effort is

    not the translation, but the Review • Plan for sufficient time – also consider time zone related losses • Inform your translators ahead of time • Ecosystem biorhythm: WWDC, Xmas, OS releases, iTC downtimes, …
  46. Organizational Skills As much info material as possible, such as

    video tutorials, support documents, review guides, etc. The Learning Curve
  47. Organizational Skills Agree on one single contact. Ideally: a lead

    developer! Agree on Q&A methods and schedule sessions Communication
  48. File Formats & Tools File Formats Native resources Exchange file

    formats • xibs, plist, strings, stringsdict, … • json, … • xliff, … • xlsx, docx, … The bigger / complex your project is, the better it is to use native files.
  49. File Formats & Tools File Formats Native resources Exchange file

    formats • Can be versioned easily • Contain ALL context • Are context themselves • Versioning difficult • Prone to loosing context • Error source Include translators in the decision
  50. File Formats & Tools Tools / Platforms Self-services on the

    web Full services on the web • No file format hassle • Easy and quick • Anonymous translators • Status tracking and statistics • Q&A handling • No file format hassle • Easy and quick • You bring your own translators • Status tracking and statistics • Q&A handling Made for your comfort, typically inefficient for translators
  51. File Formats & Tools Conclusion • Either work with files

    or online platforms - include translators • Most online platforms are very inefficient for translators • Choose wisely and be aware of dependencies and error sources
  52. News from WWDC17 New Pséùdôlängùágès (incl. RTL) New Autolayout constraints

    checks and warnings Stringsdicts can now be exported into Xliff (meh) Watch WWDC17 Session 401 (Localizing with Xcode 9)