Hi, I'm Tiago

Does your app speak in tongues?

Published on

This article is about something I’ve been regularly seeking but as the date of its publication, I cannot yet find a working solution. If I happen to find a good alternative, I’m going to post an update later.

Motivation

Unless you’re publishing an iOS-only application and abandoning the other 70% of your potential customers in the mobile market (I can see you, Clubhouse), you’re going to have multiple shared (as in duplicated) messages between iOS, Android, and possibly, Web clients.

As a matter of fact, programmers hate duplicating stuff. It violates our precious Don’t Repeat Yourself principle, and duplication always results in inconsistency. Nevertheless, those platforms don’t communicate to each other (maybe by design). Some service, platform, or app has to be used to fill the gap and share strings between them.

On top of that, you’re going to need translations as well, because most of the world does not share your mother tongue, doesn’t matter what is it.

What could one expect from a translation system?

So I’ve been seeking a solution to the issue for the past few years and I’ve tested a few promising options, but none of them would provide all the features I care about. So I’m listing them here hoping someone (or myself) interested in building a cloud-based translation service in the future happens to come across this article:

  1. Intuitive user interface: This one is a must because app translators are not always developers and you don’t want them wasting time on learning how to edit an obscure XML file, and possibly breaking a few placeholders by writing @% instead of %@. My ideal interface would be something that resembles a spreadsheet, with columns for:

    string id, base text, translated text, expected length, comment
    
  2. Shared strings between Android, iOS and Web: While some messages are platform-exclusive, I’d expect most messages to be shared between Android, iOS and Web clients with only a few changes, eg. in placeholders. If some message is platform exclusive, make it clear in the string itself and we’re good. I just can’t Write Everything Thrice!

  3. Live translation updates: Sometimes you need to fix a typo in a translation of the app that already hit the store. You won’t have all your users download a 144MiB update over their expensive mobile data connections because you wrote Find CAt instead of Find cat in the label of that button, will you? Still, the boss wants that mistake fixe; which takes us to:

  4. String versioning: I don’t want my strings file to be populated with action_ok, action_ok_version_code_25, action_ok_version_code_40. Still, I want some of them to be updated only for the next releases. Plus, developers should be allowed to edit stuff not worrying about introducing errors in the production environment.

  5. Support for parameters: translatable="false", formatted="false". Every web translation system I’ve ever tried falls short here. Parameters get randomly deleted when you try to export strings after translation. If they’re even supported at all!

  6. Formatting support: Most modern text widgets can render <b>, <i> and <em> tags in a text, so why leave them out?

  7. Support for comments and examples: Android supports <xliff:g> tags and <!-- xml comments --> while iOS supports /* C-style comments */ in their string resources files, respectively. They’re particularly useful because you can tell translators about the context that particular string is part. That would go into the | comment | column of the UI back in item 1.

In the next part of this article, I’m going to list the options that are currently available and point out some advantages and disadvantages of each one of them.

Let’s take a look at the alternatives we currently have. I’m going through the solutions I could come up with and I’m going to rate them giving one point for each of my wishlist of 7 features and I’m also going to list some additional Advantages or Disadvantages of every solution.

This is by no means an extensive list.

1. Stock translations for Android, iOS and web hosted in their own git repositories. (4/7)

Just use the tools that are already part of each platform SDK, duplicate all the strings over all the clients and rembember to edit resources for all clients each time you need to edit a string (sure I will).

This one isn’t actually a solution, but I feel that it needs a score so we can compare it with the other alternatives. If this article was a scientific experiment (spoiler: it’s not), the alternative 1 would be the control group.

So, straight to my wishlist:

  1. Intuitive user interface: ✖
  2. Shared strings between Android, iOS and Web ✖
  3. Live translation updates ✖
  4. String versioning ✔
  5. Support for parameters ✔
  6. Formatting support ✔
  7. Support for comments and examples ✔

Final Score:4/7

Advantages:

  1. No external dependency required. Support is built-in with all features for each platform included.
  2. Strings are versioned, so editing them won’t affect previous apps.
  3. Supports all features in each platform. Plurals, string arrays are all in.
  4. Free.

Disadvantages:

The first one is already a deal breaker:

  1. Everything has to be done manually1 over several files by the developers. For Android, that proably means importing or even copying manually each string from values/strings.xml to some spreadsheet, mailing it to translators (or using some automated web translator 🙈), getting the translations back and do the opposite process to other files under values-<LANG>/strings.xml, then comparing all the placholders ("%s", "%<n>$s", …) with the source language to be sure if none is messed up. Have a few hundred strings and this process can easily extend through weeks.
  1. There’s no integration between platforms at all. You have to do everything thrice for each message in every language.

  2. Change is hard. Edit one string in the source language and you have to mark that translations are needed for that resource all again.

2. Have shared strings and convert them (3/7 to 5/7)

A slightly better option would be staging a version of the string translations under a git repository and using a tool to convert them to formats supported by other platforms. This works out of the box if all clients are under the same repository, or else Git Submodules and symbolic links can be used to achieve that setup.

  1. Intuitive user interface: ✖
  2. Shared strings between Android, iOS and Web
  3. Live translation updates
  4. String versioning
  5. Support for parameters partial (depends on web conversion tools)
  6. Formatting support ✔ (limited)
  7. Support for comments and examples partial (depends on web conversion tools)

Advantages

  1. Less work than manually copying everything, but still some work.
  2. Easy to setup.
  3. Strings are under version control.

Disadvantages

  1. Requires external tools to convert between Android, iOS and the format supported by the Web framework.
  2. Probably won’t support all features from all platforms.

3. GNU Gettext (.PO) (?? — untested)

I haven’t actually tried this myself, but I suppose, if you’re using a web framework that supports GNU Gettext (you actually might be able to find a lib for each language) you can automatize part of this proccess using GNU Gettext through android2po and POLocalizedString.

4. A web translation system (3/7 to 4/7).

I’ve tried several web-based translation services but none, as the date of the publication of this article, offers the main features I look for. I’m not going to list each one of them individually because they offer the same basic stuff. Instead, I’m going to list the features that are supported by the most known services (the ones you find at the top results of your search engine when you look up ‘Android iOS Web Translation’).

As I’m now referring to multiple services instead of one, I’m going to write briefly about each item in my wishlist and relate it to features common available in such services.

  1. Intuitive user interface: ✔

Most services are intuitive enough to show the string in the base language side by side with the original string, so let’s give them that.

  1. Shared strings between Android, iOS and Web

This is not supported in any systems I’ve tested. Some of them offer a Translation Memory which might be a bit of help here, but it mainly helps one to copy translations from a project to another (eg. from an iOS to an Android project). Once you’ve done this, you’re on your own with edits.

  1. Live translation updates

This one is common enough.

  1. String versioning

None I’ve ever tried has string versioning. You either do it yourself by creating new strings or adding a version to the id. Both options are far from ideal

  1. Support for parameters

Each and every service I’ve tried lost my parameters from Android strings, even the most basic and widespread ones: formattable=false and translatable=false. The services that didn’t erase all parameters, lost them after the first edit throught the web interface.

Basic formatting with printf-fashioned placeholders ( %s, %d, %f…) usually work. Positional arguments %1$s, %2$s are sometimes not identified as placeholders (so translations can corrupt them unadvertisedly).

  1. Formatting support (limited)

Basic html format tags (<b>,<i>,<em>) are usually kept, even if they are not properly interpreted.

The services I’ve tried don’t support ![CDATA at all and either strip from the strings or fail to interpret strings that have it.

  1. Support for comments and examples

Even worse than parameters, xliff:g tags are ignored and comments are stripped out mercilessly by each one.

So what do you recomend?

As I made clear in the beginning of the article, none of the options is ideal, so I recommend none. I currently use one web service that scores 3/7 (1, 3 and 6) in my list (because live translation beats other options for this specific case), but if any other better featured option pops up, We would be glad to switch.

What’s the idea? Should I build my own thing?

Well, you probably shouldn’t, but…

I cannot help but to wonder a full featured Translation SaaS can be built including all my recommended feature, or one of the existing services could patch their system to make them a bit more usable. Well known solutions do exist that solve each one of those seven problems individually, or come pretty close to that:

  1. Intuitive user interface:

    • Steal UX inspiration from any spreadsheet app, as the existing translation services have done.
  2. Shared strings between Android, iOS and Web

    • Some script that would copy the text, replace the placeholders, convert params, comments, etc. Some mapping would have to be built (eg. %s -> %@) but that’s not really rocket science.
  3. Live translation updates

    • Existing systems do that. Barely download the last translations file and persist it somewhere into the app internal storage.
  4. String versioning

    • Not hard. Even Git could be used, as translation files are text/source files.
  5. Support for parameters

    • More mapping. Maybe some intermediary format must be used to persist the options, but doesn’t sound like too much.
  6. Formatting support

    • If it’s too hard to support all offered options over all ends, stick to one format, eg. html <b>, <em>, and this can be easily supported.
  7. Support for comments and examples

    • Some more comment mappings, eg. <!-- -> #. If block comments are not supported by any of the platforms, transform them into line comments. Again, not too hard.

References


  1. Actualy, Android Studio now comes with a Translation Editor, but its usefulness is questionable. Will one really force all translators to setup a full featured development environment, edit their translations in Android Studio, learn how to create a git patch and submit their translations to code review? Will one give dozens of people access to a private repository? Return