How to share translations between iOS and Android

How to share translations between iOS and Android

When you decide to develop an iOS and Android application for your business then localization might quickly become a relevant topic to grow globally.  You may ask yourself whether you should manage each application’s copy independently from each other or can share translation data across applications.

Platform-specific approach make platform specific tools for the localization process available to you for example like the integrated XLIFF export of Xcode.
However, if both apps offer the same functionality and display pretty much the same content you can really benefit from shared translation data.

Sharing translation data between an iOS and an Android app leads to new challenges that I will address in this blog post.

I will sketch out how to share translations across both platforms as well as how to setup a continuous localization workflow for this.


Overcoming cross-compatibility obstacles

Before we get started I highly recommend to check out the official localization documentation for iOS and Android.

Xcode provides a feature called “Base internationalization” to help you develop your internationalized iOS app. It is used to extract user-facing strings from .storyboard and .xib files. It relieves translation editors from having to modify .storyboard and .xib files inside Xcode.

However, there is a drawback. Base internationalization generates string files with cryptic names referencing the quite cryptic object ids of the interface builder:

"CH7-Yv-ryk.text" = "Nice text";

These cryptic segment names lose any contextual information and are not helpful to translators.

Imagine using such a segment identifier in a shared setup with an Android app. Your Android team would have a really hard time finding out where this segment should actually be located inside their application because it lacks any information on its context. It even gets worse if the copy is quite short or used in multiple locations with the segment name offering no help at all.

In general, developers on both platforms will benefit from well structured and meaningful key names.

You should abandon the thought of using Base internationalization in Xcode when you intend to share your translations between both apps. At least if you want to keep your whole team happy.

iOS and Android rely on different formats and structures for their localization files. Even if you have generated a nice String file for your iOS app that contains meaningful key names, you can’t just include that file in your Android app or vice versa.

Before adding an existing iOS locale file to an Android app, you need to convert your localization files between the iOS Localizable Strings and Android XML format.



Placeholder handling in iOS and Android

For example, consider the case if you use interpolation variables in your locale file. Android and iOS basically share the same c-style placeholder style but unlucky us they differ their formatting syntax.

Let’s assume in your app you want to display a greeting based on the user’s ‘name’. You want to insert that name into the string programmatically to greet every user individually with their own name using an interpolation placeholder. Unfortunately, iOS and Android don’t use the same syntax in that case. In iOS the typical placeholder would be %@, however Android uses the placeholder syntax %s. So in order to work properly on both platforms, strings containing placeholders need to be converted correctly to the syntax of the according platform.

Now, you could start writing a small script to convert the possible placeholder formats inside the locale files, however a modern localization management systems like PhraseApp handles this automatically for you. For the placeholder example, PhraseApp enables you to download your translations correctly converted into the format you want at any time without you having to care about specific conversion rules.
PhraseApp also offers an Xcode and an Android studio plugin (Beta) to allow simple synchronization with our online Translation Center.


Continuous localization workflow with PhraseApp


Starting with PhraseApp, the onboarding wizard will guide you through the initial steps including the creation of your project. Complete the wizard and created your first project. You can either initially upload your existing locale files now or do it using our plugin or client later. However, you should ensure that the c-style placeholder format is activated in your project to use PhraseApp’s placeholder conversion feature.


After setting up your account and initial project, the next step is to download and install the PhraseApp plugins for Xcode (iOS) and Android Studio. Like described in the previous section, we won’t use the Base Internationalization feature workflow in Xcode (Note that the guide for the Xcode plugin relies on the Base Internationalization feature using the XLIFF format).

If you have followed the plugin installation guides, you should now have one .phraseapp.yml configuration file inside your iOS app’s folder and one inside the Android app. At PhraseApp we call the upload of locale files push and the export or download pull. You’re now basically ready to push and pull your translations using the plugin or the PhraseApp Client directly for each specific platform. However, since we want to enable a workflow to share translations between iOS and Android there is one necessary step left. We need to customize the .phraseapp.yml a bit for each app, so let me show you how in the next step. There is a format option ‘convert_placeholder’ which we need to activate for the pull-command as shown in this example configuration file:

For Android:

For iOS:

I assume in the provided example configuration files that you want to translate your apps from English (en) to Spanish (es) and to Canadian French (fr-CA). Therefore, we have created the according locales inside our PhraseApp project before hand.

Check out the PhraseApp client configuration documentation for more details on possible options.

It’s time for your first upload! Use the plugins or the PhraseApp Client from the command line to push your locale files from one of your projects to PhraseApp. You will notice that only one locale will be uploaded as shown in this example output of the Android Studio plugin:


In the example configuration file, I have explicitly added only one push-source for the original copy (also called default locale within our system). I highly recommend to not push all locales in your continuous workflow. It’s a good idea to manage all copy and translation changes within PhraseApp from now on and to use push only to introduce additional translation segments.

If you have existing translations for any other locale, you can of course still initially push them using the PhraseApp client or uploading them inside the using the Translation Center.

Now, your translators can start editing or adding translation copy inside PhraseApp. If you should need professional translations services, you can even order professional translations through our software that are usually delivered within a couple of hours.

Whenever translations are updated you can use the PhraseApp plugin to pull those copy changes into your two applications. You can also integrate this as a build or release step. As an example you can simply add a hook to update your locales when building your iOS app in Xcode. Just add a ‘run script’ in your ‘build phases’ of your chosen target that executes ‘phraseapp pull’.


If you add new features that require completely new translation copy, you can just add the required keys to the source locale file. Using the push command of the plugin, the newly created segments will be uploaded to PhraseApp. The new segments will be created and are available for translators in the Translation Center immediately.

An improved process

Congratulations, with this simple setup you have now enabled a continuous internationalization workflow that ensures that your iOS and Android app will always share the same set of translations.

Your Android and iOS apps are now prepared to use shared translation data. Updating the apps’ copy is as easy as ‘pull’ing the updated locale file from PhraseApp. Your localization team can finally work on copy without having to bother your engineers too much. Similarly, your engineers do not have to worry about the translation process and can spend their time on developing the software.