With the increased globalization of the economy, there is an obvious need to create mobile apps that handle multiple languages in a clean and extensible manner. This is known as localization (L10n) in the software development community, and various platforms deal with it in their own unique ways. We will look at how iOS manages L10n here, and the decisions that have to be made in order to stay on top of a dynamic situation.
There are several resources on iOS L10n available, both in official publications by Apple, and some articles and blog posts written by members of the development community:
- Apple provides a home page for Internationalization (I18n), with links to several additional detailed sources, including WWDC videos.
- There is an excellent tutorial on the MacRumors iPhone/iPad Programming Forum that goes into great detail on both how to convert your app to handle L10n and managing the app on an ongoing basis.
- For apps being developed to target iOS 5, using pre-Xcode 4.5, Ray Wenderlich’s blog provides a good starting point with this blog post.
This article will take a high-level look at what needs to be done to fully localize an app. Three follow-up articles will look at the nuts-and-bolts details of how to accomplish this through building an Xcode iOS app from scratch. We’ll look at creating an app with storyboards, and the process of configuring the project to localize these storyboards. Next, we’ll cover how to handle localization programmatically, if you find you have to manipulate text before displaying it. Finally, we’ll wrap the series up with a look at how to communicate with a web service and identify the language of the data you are expecting to download.
Note: There are accompanying sample projects and shell scripts available at the AIS github.com repository collection:
These will be discussed in detail as they relate to each article, and are free to download and experiment with.
Management of Localizable Data
There are three aspects of core iOS apps that needed to be addressed to properly localize data:
- Text presented via the MainStoryboard(s)
- Text managed in the code itself
- Text downloaded through calls to a web API
Text displayed through storyboards and via code use “.strings” lookup files. Each language for which the app is being localized will have three .strings files: MainStoryboard.strings, Localizable.strings, and InfoPList.strings.
The most cumbersome aspect of an iOS app that needs to be localized are the storyboards. When you create an app, you will have one or two core storyboards available. If you create a universal app (one that will run on an iPhone and iPad), then you will have MainStoryboard_iPhone.storyboard and MainStoryboard_iPad.storyboard. If you only target the app at one of these platforms, then the storyboard will be simply titled MainStoryboard.storyboard.
The key takeaway in all of this is this: Every control created in a storyboard that displays text must be localized. In order to do this, the Xcode project for the app must be set up appropriately. (The details of this process will be outlined in the next part of our series.) But the core process is this:
- Create your project.
- Enable “Base Internationalization.”
- Add any additional languages necessary to the project.
- Create/Modify your storyboard to satisfy the needs of the project.
- Run the UpdateStoryboardStrings.sh (provided as a download in the “iOSL10n” github repository) script to extract the text from the storyboard and add it to the .strings files used as lookups for the storyboard.
- Each .strings file follows a key = value format for identifying the object that must be modified, and the value to be substituted.
- These .strings files must be edited to provide the necessary translations.
Every time a new text object is added to the storyboard, the corresponding .strings files must be updated with the lookup text that corresponds to that object. UpdateStoryboardStrings.sh automates a good part of this process, although you will still be responsible for providing the translations.
Check back next week for details on how that whole process works, and links to the shell script and sample project that demonstrate localization in storyboards.
We will look at how all text that is generated through code has to be localized as well in a later part of the series, but in code, typical functionality to localize text will look something like this:
NSString *myString = NSLocalizedString(@”myStringKey”, @”This is my string!”);
NSLocalizedString(key,comment) is a Cocoa function that takes the string @”myStringKey” and looks up the intended translation in the appropriate Localized.strings lookup file. A few points:
- There will be a Localized.strings file corresponding to each language for which the app has been localized.
- ”myStringKey” is the actual key used for the lookup. “This is my string!” is nothing more than a comment in this function.
- If the key is not found in the lookup file, ”This is my string!” is not what is displayed as the text. “myStringKey” will be used instead.
As for localizing storyboards, a shell script has been created (UpdateCodeStrings.sh; also available for download) that parses all of the *.m files and looks for “NSLocalizedString.” It takes all found occurrences, and looks for all of the keys in each of the Localized.strings files. If one is found, then nothing happens. If it is a new key, however, then the following (as an example) is appended to the end of each file:
/*“This is my string!”*/
“myStringKey” = “This is my string!”;
The key/value pair is determined by the key/comment pulled from the NSLocalizedString() function. The task of actually providing the translations, again, is left to the user. But the manual process of adding each key/value pair has been automated.
The final aspect of localization is handling text being downloaded through a web service. The final part of our series will provide an example of how to determine the current locale of the device on which your app is running. Using that information, your app can then send a cookie to the web service, using an accepted international code (for example, English = “en”). The server can then use this to determine the language of the data that is to be sent back down.
Code samples for both the client and server side will be provided with the final article.
If you are rigorous about following the steps outlined above and in the companion articles, then localizing your iOS app is relatively painless. There are some ‘gotchas’ involved, which I’ll detail in the series, but overall the process is straightforward and will provide for a complete coverage of all of your iOS localization needs.