iOS App Localization: Challenges and Lessons Learned

In this software and game localization project, our team localize two iOS applications, Sakura Fly and Track My Time, into two languages, Chinese and Russian (we use machine translation for Russian as no one in the team speaks this language). Click here for the application files.

                                               

We met some challenges while localizing the two applications. Comparatively speaking, it is easier to localize Sakura Fly. The only challenge we meet is to wrap up strings that need to be translated. In two strings, there is a line break mark “\r”. If we include it in our strings, we will be unable to import the translated strings back into Xcode; if we exclude it from the strings, an error will occur (we think the reason is the string is in “NSString stringWithFormat”). Although “\r” should function as a line break, the strings do not show up in two lines in the application. Therefore, we removed “\r” in the strings and then we were able to localize the strings. As Russian text expands, we also adjusted the width of buttons to make sure all the strings can fit.

We met more challenges when localizing Track My Time.

First, the compiler uses “static NSString * const” for defining. However, we were unable to directly wrap up strings in this expression. After our research, we found that the express in the expression “#define”, we can wrap up strings with the express “NSLocalizedString”, and although there are a few differences, “#define” can be a replacement for “static NSString * const” in most scenarios. We replaced a few “static NSString * const” expressions with “#define” and did not notice any differences, so we knew “#define” would work. We replaced all “static NSString * const” with “#define”, and finally, we could wrap up strings.

Some strings exist in a .h file, and could not be wrapped directly. We created a .m file and migrate all the content in the original .h file in it, so we could wrap all the strings successfully. We also modified the code in the .h file and import the new .m file in it to ensure the application can function.

In the application, there is a list of activities. At the beginning, we found the strings a .m file. However, after a pseudo translation, we found they were not the one we need to wrap. The correct strings are in a property list called Activities.plist. We researched how to localize .plist. It is actually quite simple—all we need to do is to find the “localize” button in the Utilities pane, click it and choose the language we need.

The application has a launch image. We spent a lot of time researching how to localize it, but we found that it could not be localized. The image is in a folder called Images.xcassets, and the files in .xcassets cannot be localized directly. The best option is probably to delete the original codes and files for the launch image and put it in a storyboard. In this way, we can localize the image with the Localize button. However, recoding requires a lot of efforts and we did not think it was feasible within limited time, so we had to give up localizing the image.

 

When developing the application, the compiler made the date format “dd.mm.yy”, which is used in Russian but not in China or the United States. We attempted to adjust the code—we thought we could retrieve the locale and add an “if” function to let different date format shows accordingly; however we failed to retrieve the locale. To be honest, none of us know how to code in Xcode, so we might need to learn the programming languages first.

While we localizing the application, we learned a very important lesson—pseudo always helps. Also, our experience can provide a lesson for the clients—if you want to localize or internationalize your application, make sure your product is localization-friendly or internationalization-friendly; otherwise, you might need to devote more time and efforts to adjust the codes. Last but not the least, we need to learn Objective-C during this winter holiday.