I have an iOS and Android app that supports +5 languages, so I thought it would be great if I could put the localized string files on a server and once the user open the app, I download the file and load it in the app.
The challenge so far was in iOS, since I need to reference all labels, buttons .... etc from my XIB and Storyboard files to be able to assign the corresponding text/placeholder to all of the UI elements.
Any approach/technology/idea about doing like one file on a server that contain the localization for both platforms and to be easy to implement since the app has reached 50+ screens.
I'm neither an Android nor iOS developer, but I have experience doing the file conversion part of this.
You're no doubt looking for a product to do the heavy lifting, but I'm going to try and answer your question as though you're rolling your own.
It's not hard to write a file converter from iOS to Android strings (or vice versa) but the real challenge is how to manage the workflow and how to keep a common base of feature support that works on both platforms.
Assuming your process begins by extracting translatable strings from your iOS code base, let's start with the translatable file formats you have available to you.
Xcode supports XLIFF 1.2 which is an ISO standard and is used by various translation products and translation industry professionals. This would be a sensible "source" format to use in your workflow. i.e. export your strings to XLIFF files and get them translated. You could then do lots of things with these files quite easily. Namely importing back into Xcode and converting to Android XML files.
From your translated XLIFF files you could generate a set of Android strings.xml files. Writing a converter is not particularly hard, but it depends what features you need. In the simplest instance you would pull a set of key/value pairs from XLIFF and render them out as Android strings.
The following (simplified) XLIFF in the Xcode style:
<xliff version="1.2">
<file source-language="en">
<body>
<trans-unit id="foo-message">
<source>Foo</source>
</trans-unit>
</body>
</file>
</xliff>
is equivalent to the following Android strings.xml
<resources>
<string name="foo-message">Foo</string>
</resource>
I'm not including any code here. If your preferred language supports XML parsing, it's not much of a leap to extract {"foo-message": "Foo"} and render it out.
Note that your translated XLIFF files will look a little different. You'll be pulling out the <target> elements instead of the <source>.
As already mentioned in the comments, you would need to convert your formatted strings such that "%@" becomes "%s" and so on. This can be done with RegExp, but again the complexity depends on the range of what you need to support. For example, can you just stick to string/object placeholders or are you using fancy things like floating point precision, or custom padding characters? Avoiding them if you can will make conversion easier.
Translatable strings tend not to use the full power of printf syntax, so you may be able to get away with a basic RegExp replacement that just looks for "%@" symbols. One thing to beware of is that multiple arguments must be numbered in Android. ("%@ %@" would have to become "%1$s %2$s"). You could avoid that headache by always using the argument number in the source format. (I believe "%1$@ %2$@" is legal in Objective C, but I'm not an iOS dev).
Watch out for false positives like "20% off" (this is actually a space-padded octal "% o"). In Android you could flag the XML string element as formatted="false" but not sure how you'd mark that in iOS.
This the trickiest problem I've come across. Although both formats support plural forms, iOS is a bit of a nightmare.
Android is neat:
<resources>
<plurals name="apple">
<item quantity="one">1 apple</item>
<item quantity="other">%d apples</item>
</plurals>
</resources>
But XLIFF has no native support for plural variations, so the equivalent in Xcode flavoured XLIFF is much more complex. Recent support added to Xcode uses separate translation units for each "quantity". These live within a <file> block that maps to a .stringsdict file. I'm not going to get into it here.
I can't advise on how best to dynamically load translations from files stored remotely, but I would consider whether you want your app to be unavailable when offline, and perhaps more importantly whether you want to introduce an external dependency.
I can see the advantage of being able to update translations without shipping a new release of your app, but Xcode's import function seems to take care of a lot of the hard work, particularly when it comes to plural forms. It also saves you the hassle of merging new source strings into your translated files. To me it makes sense to compile them in, but then I've never experienced Apple's approval process :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With