Every app needs localization even when it’s small and “single language” app. You never know when another language could be added. Even when you’re totally sure there will be no more languages in the app, you should never have strings written directly in the code for many reasons. So you can create some custom enums, constants, whatever or you can use standard default localization keys. Guess what’s better. ?
Localization is not only about strings - also dates, numbers or currencies must be localized and formatted according to user’s locale. Since it’s handled by iOS itself, let’s talk about strings localization for now.
Following the text is not any kind of universal truth or recommendation how you should do it. It’s just the way we do it. You can use it, get inspired from it but of course it doesn’t have to be suitable for everyone.
Where is the problem?
Let’s break it into 2 levels. First one is localization in the app on the code level. Second one is management and translation of the strings by non-programmers.
In the app itself it’s all good. On the lowest level we use standard .strings format with a few tools on top of that to make it more comfortable and error proof (as described in detail below). However the problem is how to create Localizable.strings? A programmer defines localization keys and someone has to create translations.
You can send all Localizable.strings files to a translator but it’s a very confusing format for a non-programmer and there is also high probability that the file will return damaged in some way (forgotten semicolon, quotation marks etc.).
3rd party solution
Right, this problem has been resolved a long time ago. There is a lot of services created especially for translating apps. Probably the most famous is PhraseApp, but there is also Smartling, transifex and many others. All these services has 2 things in common.
- It’s just overkill - We found out that we really don’t need the beast like PhraseApp. Accounts, history, graphs and tons of other features.
- It’s pretty expensive - Sure, we wouldn’t go bankrupt, but why to pay for something we don’t need?
Before you start googling something like “phraseapp alternative”, give a chance to another approach.
We all know spreadsheets… Excel from Google with a real-time collaboration, but you might be surprised how strong Google Spreadsheets are! You can do awesome things with Apps Script, it has good web API and there is also a lot of open source libraries for various programming environments. We have even used a spreadsheet as the backend for a small app already, but that’s a topic for another post. So if it can replace the backend it should be able to handle few localization strings.
We create a new spreadsheet with columns for localization keys and supported languages for every app. Keys can be different for each platform because of different naming conventions, that’s why we have more key columns (eg. key_ios, key_android). For example basic table looks like this:
|welcome.register||welcome_register||Create account||Vytvořit účet|
This format is good for translators, as mentioned above - it’s just an excel sheet, everybody knows how to work with that. Also it’s a great format for generating .strings file, because it’s a machine readable table. Win-win.
Back to apps
OK, we have a spreadsheet with all strings, but how to transform it to Localizable.strings? Long time ago we were using node.js tool localize-with-spreadsheet but as you can see, it’s a little outdated ?? and we also had to install node.js, which didn’t make our iOS guys happy. Therefore we decided to create our own tool written in Swift. ? It’s called ACKLocalization and it does the same job as the node tool mentioned above. It has a few input parameters like spreadsheet identifier, output path etc. and based on these inputs it generates Localizable.strings. If you would like to try it see usage guide on the github page.
Last part of our localization toolchain is SwiftGen. It takes Localizable.strings and generates nice and error-proof enums.
So instead of
titleLabel.text = NSLocalizedString("order_list.title", comment: "")
titleLabel.text = L10n.OrderList.title
Our approach doesn’t have to be good for everyone but it’s free, easy and simple and last but not least it’s open source! ...except Google Spreadsheets of course. ? You can fork and edit ACKLocalization or create your own download script, you can replace SwiftGen or you don’t have to use it at all. Anyway we will love to hear any feedback from you on our Twitter or right on ACKLocalization GitHub page.
If you want to know how to nicely integrate ACKLocalization and SwiftGen to Xcode project, see our brand new iOS-MVVM-ProjectTemplate which we have published within the grant from Ethereum Foundation.