Text localization in iOS applications

Pramod Manjunath
Practo Engineering
Published in
6 min readDec 28, 2017

Localization is a vast topic but let’s try to keep it short.

Why Localization?

If your iOS application targets a diverse multi-lingual audience, you will need to customize the application to suit their native language, format etc. Better the nativity, more the chances of the app gathering wider regional audience.

Challenges

Developers who wish to localize their application fall in one of the 2 categories:-

  1. Ones who realize it when most or the entire app is developed.
  2. Ones who realise the need for it before hand and want to plan accordingly.

Sometimes, even for the latter, it ‘feels’ like a big burden to cope with localization in parallel.

NSLocalizedString( ) is here

NSLocalizedString() is the solution for either cases mentioned above. Enclosing strings written in your code in this macro solves half of your problems.

For the latter this is not a big effort in their development.

For the former, you might have to just find a good way/hack to enclose all strings in the application in the above macro (Manual labour? Find and Replace? Scripts? You’re the master!).

Strings hard-coded in the interface builder files like .xib and .storyboard are easier to deal with in either of the above cases.

Done! What’s next ?

That’s it. Your application is now ready to be localized.

Xcode gives us the ability to export all localizable strings into a single file per language into a format knows a XLIFF, a standard for passing localizable data between systems. This can then be used for translation and import.

PROJECT

The same project for this article can be found here.

  • The project is a simple contacts list app where on clicking on each entry in the list pops up an alert showing the name and the number.
  • Has localizable strings in both code and hard-coded in interface builder files.
  • Includes language support for base (EN) and German (DE).

More details in the GitHub repository.

Pre-requisites

Ensure the Use Base Internationalization option is checked and the desired target languages are added in the Localizations section of the Project settings as shown below.

Pre-requisites

Enabling localization

In ViewController.swift, there is reference to a couple of strings in the code enclosed in the NSLocalizedString() macro.

NSLocalizedString("Name: Mr. %@ %@ \nPhone: %@", comment: "The variables are ordered as per constructs for english. Can be reordered for other languages")

This above statement has a comment which the translator can read to understand more about the string being translated. It is optional.

NSLocalizedString("OK", comment: "")

The above one is pretty straightforward and hence no comment required.

Strings in interface builder files

The image above shows the strings hard-codes in the interface builder files. Developers do not need worry about such strings as the XLIFF exporter handles them well.

XLIFF export

Now is when the actual work starts.

Select project name on the project navigator, select the project name under the ‘PROJECT’ section. In the menu option select Editor -> Export For Localization....

This will popup an option for you to select/deselect the already supported languages in the application. If it is just your base language, then nothing pops up. Save the file(s) to your hard drive, depending on the number of target languages.

Option for exporting (and importing) localizations

More about the XLIFF format can be read online. It exports the translatable strings in XML format and aides passing these strings between systems which understand the standard and can be used for translation.

Translation

The XLIFF files are ready for translation. All we need now are systems which understand the given format and aide the translators in mapping the translations. The result of any such translation is also an XLIFF file. A sample online tool for your reference.

Once the translated XLIFF files are obtained, the developer needs to select Editor -> Import Localizations... and selected the translated files and import them to the project.

As a result of this a couple of things can be observed in the project :-

  • A Localizable.strings file is formed for every supported language. Notice comments wherever provided in the code.
  • Every interface builder file will have a base localized file and 1 .strings file for every supported language.

P.S: As a reference, the exported XLIFF (pre translation) and the XLIFF ready for import (post translation) are present as a part of the sample project in the GitHub repository mentioned above in the after-localization branch.

Run the app

After all the effort, time to put it to test and check if it works.

Run the app first in the base localized language. In our case it is default to English. You can run the code in the after-localization branch in the above mentioned GitHub repo.

Then change the device language to German (DE) and check again. It should look like below.

What else ?

Translation is not as straightforward as it is thought to be. Each language has its own constructs which needs to be respected in order for the app to be taken seriously by the audience.

One such thing shown in the example is the placement of the first name and the second name in the alert popup for different languages.

If observed closely, the English version shows Mr. <First name> <Last Name> whereas the German version has Herr. <Last Name>, <First Name>.

Although it might seem trivial with the example at hand, it might prove handy when encountered with situations that require such re-ordering of variables in a translatable string.

How is this done ?

The Localizable.strings file of the translated project gives the secret away.

/* The variables are ordered as per constructs for english. Can be reordered for other languages */"Name: Mr. %@ %@ \nPhone: %@" = "Name: Herr. %2$@, %1$@\nTelefon: %3$@";

When observed, the variables in the string are ordered slightly differently on the right hand side i.e. translated text.

This simply indicates that in the translated string, just swap the first 2 variable strings which is exactly what has happened in our example project.

This was also possible because the code written to localize a string involving variables within it allowed for it to be localized.

let message = String(format: NSLocalizedString("Name: Mr. %@ %@ \nPhone: %@", comment: "The variables are ordered as per constructs for english. Can be reordered for other languages"), contact.first_name, contact.last_name, contact.phone)

Do observe the String(format:) enclosing the NSLocalizedString() macro which enabled the export of the string to be localized.

What would happen if we swapped the usage of String(format:) and NSLocalizedString() in the above code. Feel free to experiment with this order and also the order of the variable strings in the sample project.

At Practo..

..we use the xliff export/import feature extensively as we have a presence in Indonesia and Brazil as well and have localized our applications in their respective languages. This gives us a lot of flexibility in terms of the format using which we exchange localizable strings between the development and the translation team.

All we do once the development of a feature/task is done, is export the localizable strings in the xliff format and share it with the team helping us with translations who take not more than a couple of days to hand us the translations back in the xliff format. The team uses one of the many online tools to read and write to the xliff. All we do is import them using the tool and the app is localized. Then we run through the app to make sure all text literals and localized and iterate.

And Finally…

Localization as a topic does not end here. Hence the article is named ‘Text Localization’. The article attempts to cover some aspects of it. However, i might not have experienced the full power of the .xliff tool provided by Apple and if there are feedback/comments on the article, it would be great to improve on it. Localization spans different aspects of app development. Basic ones (apart from text) being date, time, currency etc etc. Another article, Another time!

Sample project

Follow Practo Engineering on twitter for regular updates. If you like this article, please hit the applause icon to recommend it. This will help other Medium users find it. We are also hiring. Visit practo.com/careers to know more.

--

--

Pramod Manjunath
Practo Engineering

Foodie, iOS dev, hobby cook and photographer, opinions are purely my own.