So, you've got an app, and it's downloading like crazy, and you begin to think: Maybe I should translate it to some other languages. Swedish, for instance. Maybe french. I'll show you how to set it all up in Xcode 4.5, and how i automatically translated my latest app using the Microsoft Translator API (which is free for small uses like ours).

Of course if yours is a big app, you should pay human translators to do a proper job. But if it's a case of no-budget-itis, and the choice is between no translations and not-quite-perfect automatic translations, then this technique might be worth considering.

And even if you would never consider using machine translations in your app, this post might be useful for you to learn how to set up your project for localisation.

Get ready to localise

Firstly you need to setup your app for localisation. These basic instructions are worth repeating because i couldn't find a good guide with up-to-date steps for current versions of Xcode.

  • Firstly if you have any strings in your XIB files, do what it takes to move these into your code.
  • Do a find all in the project for >@"< (don't include the angle brackets) to find all your strings, and convert them to NSLocalizedString(@"My English String", nil); format.

Project setup

Next up, we need to get the project ready with strings files for the different languages.

  • In the supporting files group of your project navigator, add a new file (use the Resource > Strings template) and call it 'Localizable.strings'. The file name is important.
  • Select the new file, and on the right pane (cmd+option+1), click on 'Make localized', and choose english for now.
  • You won't see this in Xcode, but this will make the en.lproj folder (it shouldn't already exist), and move the strings file there. Have a look in finder to verify.
  • Select the project in the project navigator (cmd+1), select the project in the main editor, then select the Info tab.
  • At the bottom you should see an empty list of localisations. Press '+' and select the languages you want to support. I went for all the languages in the initial dropdown except zh-hant (none of the obscure ones in the 'other' list, these probably aren't covered by the MS Translator API).
  • This will make es.lproj, fr.lproj, etc folders which will each contain a Localized.strings file. Have a look in Finder and check it worked.
  • For chinese, i'd just go only the zh-hans variant, it's 'simplified' vs the 'zh-hant' which is the traditional version.

Generate your initial strings file

For this step, we want to use genstrings to scan your code for all the NSLocalizedString calls, and use this to create the initial english Localized.strings file. We'll be making a script to do this in just the right way for your project, so you can run it again later.

Firstly, you need to open the terminal in the base folder of your project (if you do ls you should see the xx.lproj folders). Now we need to fine-tune a find command that gets all the right source files and skips third party libraries etc. Start with running this:

find . -name \*.\[mh\]

If this brings up source files or folders you don't want included, eg 3rd party libs, maybe try something like this:

find . -name \*.\[mh\] -not \( -path "./Mobclix SDK/*" -or -name "Appirater*" \)

Anyway it's up to you to tweak your find command to include/exclude the correct source files. Once you've got the find command just right, you can make the strings using genstrings by appending | xargs genstrings -o en.lproj:

find . -name \*.\[mh\] | xargs genstrings -o en.lproj

This will scan all your source files, and generate a basic english strings file for you. Do cat en.lproj/Localizable.strings and have a look at what it generates. It should look a bit like the following:

/* No comment provided by engineer. */
"Afternoon" = "Afternoon";
/* No comment provided by engineer. */
"all-day" = "all-day";

Just go through that file and check that it seems to have gotten everything it should have in there. Next up, we're going to use the Microsoft Translator API to translate it into all the other languages you chose earlier.

Microsoft Translator API

I chose the MS Translator API because it's free for small uses unlike the Google one (which is arguably better quality), and a million times better than the MyMemory one (don't waste your time like I did using it!).

Firstly, you need to sign up for the API. Follow the instructions here: http://msdn.microsoft.com/en-us/library/hh454950.aspx.

  • Sign up for a free translator: https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb
  • Then create an app: https://datamarket.azure.com/developer/applications/
  • Note: I had to change the 'secret' to something with only characters in it for some reason. Might be worth you doing the same.
  • Note the app's secret and client id for use in AutoTranslate.

AutoTranslate

This is where things get interesting! This little command line tool will localise any strings that need it, the idea is that you could run it daily on your build server to localise anything that's been added since the last run (it will only translate new strings that aren't translated yet).

I've put my AutoTranslate app up on github, you can grab it here:

https://github.com/chrishulbert/iPhoneAutoTranslate

Basically you'll want to pull it down, enter your client id/secret in the AzureAccessToken.m, compile it, and run it from the base folder of your project that needs translating.

Testing

One thing that i spent forever trying to figure out, is that you have to make sure you delete the app from the simulator and re-install it for the localisations to start working so you can test them.

Good luck selling to foreign markets! Hopefully they're not all app pirates out there...

Thanks for reading! And if you want to get in touch, I'd love to hear from you: chris.hulbert at gmail.