Painless “translations” for Mobile Developers
Tags: translations, ios, android, mobile
Published: 2019-10-13 18:40:31

Hey! If you like my articles please follow me on [Twitter](https://twitter.com/michrogowski)  Thanks!

## Translation vs Localisation
**Translation** - the process of rendering one text to another, for example Polish to English - “ciasto” -> “cake”
**Localisation** - This is more thorough process, it addresses cultural expectations, for example date format UK - Day-Month-Year -> US - Month-Day-Year.

## Plurals - cardinal type 😱
We can look at English (en_GB)
``` python
1 month
2, 3, 4 + months
```
Easy right, but what about other languages - polish: (pl_PL)
```python
1 miesiąc
2 miesiące
.
5 miesięcy
.
.
22 miesiące
```
In polish we have 3 possible plural forms of `month`. How can we manage it in our code? Android and iOS store translations differently, they are using different format `.xml` vs `.strings` - singulars and `.stringsdict` - plurals. Nonetheless they have common plural categories:
**Zero, one, two, few, many, other** — You can see rules for the categories for each language at [CLDR Language Plural Rules.](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html). [Here](https://github.com/unicode-org/cldr/blob/2dd06669d833823e26872f249aa304bc9d9d2a90/common/supplemental/plurals.xml) is xml format you can use if you would like to create your own parsing script.

Android plural example
``` xml
<plurals name=“you_have_x_points”> 
	<item quantity=“one”>You have %s point</item> 
	<item quantity=“other”>You have %s points</item> 
</plurals>
```

iOS Plural example
```xml
<?xml version=“1.0” encoding=“UTF-8”?> 
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”> 
<plist version=“1.0”>
<dict>
	<key>Older than %d month(s)</key> 
	<dict> 
		<key>NSStringLocalizedFormatKey</key> 
		<string>Older than %#@months@</string>
	 	<key>months</key> 
		<dict> 
			<key>NSStringFormatSpecTypeKey</key> 
			<string>NSStringPluralRuleType</string> 
			<key>NSStringFormatValueTypeKey</key> 
			<string>d</string> 
			<key>one</key> 
			<string>%d month</string> 
			<key>other</key> 
			<string>%d months</string> 
		</dict> 
	</dict>
</dict> 
</plist>
```

Android xml is very straightforward but if you want to understand more details about .stringdict structure just read this apple [documentation](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/StringsdictFileFormat/StringsdictFileFormat.html). If you have any questions I’ll be happy to help :)

## How to translate your app  
### Native way 
**Android** you can use [Google Play App Translation service](https://support.google.com/l10n/answer/6359997)
**iOS** I don’t think there is native translation service if I’m wrong please update me! :) 

### Do It Yourself
You can manually manage translations, in Xcode you can export/import [.xliff](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LocalizingYourApp/LocalizingYourApp.html) file and send it to translators. Android Studio has [Android Studio Translation Editor](http://tools.android.com/recent/androidstudio087released)

### 3rd party Translation Service
For everyone this term may mean something else, but in my opinion Translation Service should provide at least few functionalities for you:
* Divide translations per application - different “folders”
* Import export functionality
* Providing API or/and scripts you can use to make translations part of your CI / CD processes.

There are a lot of paid solutions and few open source - if needed you can create something yourself which would better fit your needs. 

In my opinion the best part for developers is API or script that you can use to automate whole process. I will describe example flow which you can implement in your teams - it was created by my colleagues and me.
1. **Create list of supported languages.**
2. **Send strings that should be translated from apps to Translation Service** - it should be automated. Our CI every time after merge is checking does this string already exists in our Translation Service database, if not it will create new record to be translated for this app. Script has to know where origin (usually English) strings are, and how those are stored to get value, context and check is it plural.
3. **Notify translators** - if you have internal translators you can just setup web hook to send slack message that new strings are waiting to be translated, or notify external agency and export all files to translate unless you can give them access to your translation service.
4. **Receive translated string** - same as sending it’s done by CI and internal script, while fetching translations for each string it automatically generate new files for iOS (.strings, .stringdict) and android (.xml)  to always have most recent translations in apps. When git diff is not empty, it automatically creates new pull request! We could have just add new commit but we decided that new pull request gives us more control over it - it has to be manually merged.

## Localisation
Remember to always use correct locale in your app for things like date format, metric system, currency code or symbol etc. It’s very important and may be very misleading for your users if it’s done incorrectly. Most of use cases are supported natively by both platforms so don’t write it on your own just use ready native solutions.

## Keep in mind
* If your company is working with external translators remember to educate them! Educate about parameters, escaping, special characters etc. If you will not educate translators how they should translate it, you will spend a lot of time fixing translations to make them work.

* Go through all translations, you can UI Test or Unit test them. Check that there are no crashes, that in string with two parameters translators didn’t switch them, and now you’re sending bad parameters types, for example Int instead of string. Just double check it.

* Fallback - this is mostly business decision, but I would not recommend any complex fallback mechanism. I’m always trying to use English version if translated version doesn’t exists, it pretty secure because usually  people immediately would notice it’s just not translated - falling back from Mexican Spanish to standard Spanish may be risky and just confuse your user.

* Remember to also translate and localise assets, store strings like: “what’s new” etc.

* Check your interface for RTL (right to left) languages, make sure it works and looks good.

## Summary
It’s very important to do it correctly, it opens new markets for your app and really change user experience. On the other hand if done incorrectly it may be misleading.

If you have any question just add a comment or message me directly on social media 👾