Software Localization
Internationalization and Localization
of an iOS application
For this project, I internationalized and localized the iOS application “Round and Split” into Russian (my project partner localized it into Portuguese). The app is a tip calculator for three custom tip rates, including the most common ones in the US (15%, 18%, and 20%). It also has the functionality of rounding the total, splitting it between diners and sending out email reminders with pre-populated subject lines in case one person owes money to another.
Internationalization Challenges
1. Project Configuration
Project configuration didn't really present any challenges. The “Use Base Internationalization” option in the Project Settings was already enabled by the program's author, so I just added Russian and Portuguese (Portugal) to the list of languages I was going to localize into.
2. Code Internationalization
2.1. Working with Swift
This project presented several internationalization challenges. First of all, the program was written in Swift, which I had never worked with before. Swift files are not localizable "by default," so I had to figure out a way to make them so.
Thanks to the article Localization in iOS tutorial using Swift, I found out that to do that, I need to manually create the file Localizable.strings in the same folder as my Swift files are located. This file is localizable. To enable localization, I clicked "Localize" on the right panel. After that, I checked "Russian" and "Portuguese" (the languages I configured in the Project Settings) and got Localizable.strings files for all three languages: English, Russian and Portuguese.
2.2. Externalization of User-Facing Strings
The next step was externalizing user-facing strings of the .swift files. To do that, I went through all the files and wrapped the relevant strings in a macro NSLocalizedString following this format:
"Version" becomes NSLocalizedString("Version", comment: "")
2.3. Population of the Localizable.strings Files
The following step was to populate Localizable.strings with user-facing strings content that I was going to localize. A long way to do that was to manually go through all the project files and copy the content of wrapped strings to the Localizable.strings file. But from the article How to localize your iOS app, I learned a quicker way. Using Terminal (opened in the same folder where the .swift files are located), I ran a command "genstrings -o en.lproj *.swift." The program called by this command goes through all the .swift files, checks the wrapped strings and copies their content into the Localizable.strings file for the English project in the format acceptable for localization, i.e.
"A reminder email about your request is sent." = "A reminder email about your request is sent.";
I repeated the same command for Russian ("genstrings -o ru.lproj *.swift") and Portuguese ("genstrings -o pt-PT.lproj *.swift"), and in a matter of seconds got populated Localizable.strings files for all three of my languages.
2.4. Export and Import of the Localizable.strings
After that I exported the .strings files for localization, opened and translated the resulting .xliff files in Visual Studio, and imported them back to Xcode. Then, I edited scheme, changed project language to Russian and after rebuilding the project got a (nearly) fully localized program.
Localization Challenges
1. Non-localized UI
Why do I say "nearly"? Because after rebuilding the project in Russian, QA check revealed that not everything was localized. Namely, the "CLEAR" button remained in English. Using Find command, I located it in the file NumericKeypadView.swift. It was hidden between the Unicode symbols for zero-width space (u{200b}), and I had to strip it out those symbols in order to make localization work. And it worked!
keyStr = "\u{200b}CLEAR\u{200b}” becomes keyStr = NSLocalizedString("CLEAR", comment: "")
2. Text Expansion
My second localization issue was Russian specific, namely text expansion. I encountered it only once, in the Acknowledgements link. To resolve it, I changed the translation (directly in the Localizable.strings (Russian) file in Xcode) to a shorter one, and it did fit nicely.
3. Locale Hardcoding
The third major localization issue was the fact that originally the program didn't respect the Region Format settings. After they were set to Russian, currency was still showing in USD, and the decimal separator was still a dot instead of a comma. Technically, the author of the program tried to address it by including the UI element for turning on and off a dot as the decimal separator (see picture above), but it didn't work properly for decimal separation, and it didn't work at all for currencies (see picture below).
I started looking through all the files closely and found that the file MainViewController.swift contained the hardcoded en_us locale identifier. After commenting out all the lines of the code mentioning "locale," the problem was resolved, and the program started observing the Region Format settings.
Conclusion
This concluded the process of internationalization and localization of the "Round and Split" application. It is fully localized and runs without any errors.