Internationalization Tutorial for iOS [2014 Edition]
Creating a great iOS app is no small feat, yet there is much more to it than great code, gorgeous design and intuitive interaction. Climbing the App Store rankings requires well-timed product marketing, the ability to scale up along with the user base, and utilizing tools and techniques to reach as wide of an audience as possible.
International markets are an afterthought for a lot of devs, but thanks to the painless global distribution provided by the App Store, any iOS dev can release their app in over 150 countries with a single click. Asia and Europe alone represent a continually growing pool of potential customers, many of whom are not native English speakers, but in order to capitalize on the global market potential of your app, you’ll need to at least be conversational in the language of app internationalization.
This tutorial will guide you through the basics concepts of internationalization by taking a simple app called iLikeIt and adding internationalization support. This simple app has a label and a You Like? button. Whenever the user taps You Like?, some optimistic sales data and accompanying image fades in below the button.
But currently, the app is English only – os vamos a traducir!
Note: Another important aspect of internationalization is using Auto Layout, due to changing text sizes. However, to keep this tutorial simple we will not be focusing on Auto Layout, as we have other tutorials for that.
Internationalization vs Localization
Before you start working your way through the tutorial, it is important to know the difference between internationalization and localization, as these concepts are often confused.
Simply put, internationalization is the process of designing your app for international compatibility. For example:
- Handle text input, output processing in the user’s native language.
- Handle different date, time and number formats.
- Utilize the appropriate calendar and time zone for processing data.
Internationalization is an activity that you, the developer, perform by utilizing the system provided APIs and making additions and modifications to your code to make your app as good in Chinese or Arabic as it is in English.
By contrast, localization is merely translating the app’s user interface and resources into different languages, which is something you can and should offload to someone else, unless you happen to be fluent in every language your app will support :)
The first step is to download the iLikeIt starter project you will use throughout this tutorial.
Open the project in Xcode 5 and run the app on the simulator. You should see the following appear after you tap ‘You like?’:
As you can see from the screenshot, you will need to localize 4 items:
- UI Element: ‘Hello’ label
- UI Element: ‘You Like?’ button
- Sales Data Text: ‘Yesterday you sold 1000000 apps’
- Image Text: ‘I LIKE IT’
Take a moment to browse the files and folders to familiarize yourself with the project structure. Main.storyboard contains a single screen which is an instance of the
Separating text from code
Currently, all of the text displayed by the app exists as hard-coded strings within Main.storyboard and ViewController.m. In order to localize these strings, you need to put them into a separate file. Then, rather than hard-coding them within your methods, you will simply reference the strings using the file in your bundle.
Xcode uses files with the “.strings” file extension to store and retrieve all of the strings used within the app, for each supported language. A simple method call in your code will lookup and return the requested string based on the current language in use on the iOS device.
Let’s try this out. Go to File > New > File. Choose Strings File unders the Resource subsection as shown below:
Click Next, name the file Localizable.strings, then click Save.
Now that you’ve created the Localizable.strings file, you need to add all of the text that is currently hardcoded into the app. You need to follow a specific, but fairly simple, format like this:
"KEY" = "CONTENT";
These key/content pairs function just like an NSDictionary, and convention is to use the default language translation of the content as the key: e.g. for “You Like?” you would write:
"You like?" = "You like?";
Key/content pairs can also contain format strings:
"Yesterday you sold %@ apps" = "Yesterday you sold %@ apps";
Now switch to ViewController.m, and find the viewDidLoad method. Currently, the app sets the text for the likeButton and salesCountLabel as shown below:
_salesCountLabel.text = [NSString stringWithFormat:@"Yesterday you sold %@ apps", @(1000000)]; [_likeButton setTitle:@"You like?" forState:UIControlStateNormal];
Instead, you will need to read in the strings from the Localizable.strings file you created earlier. Change both lines to use a macro called
NSLocalizedString as shown below:
_salesCountLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Yesterday you sold %@ apps", nil), @(1000000)]; [_likeButton setTitle:NSLocalizedString(@"You like?", nil) forState:UIControlStateNormal];
Macros wrap up a longer snippet of code into a more manageable size, and are created using the #define directive.
If you’re curious what the
NSLocalizedString macro does, control-click on
NSLocalizedString where it is defined as follows:
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
The NSLocalizedString macro uses the localizedStringForKey method to look up the string for the given key, in the current language. It passes nil for the table name, so it uses the default strings filename (Localizable.strings). For full details, check out Apple’s NSBundle Class Reference.
If you use this method, you can put a comment for each string that will appear next to the default strings as an aid for the translator. For example, you could add a comment indicating the context where the string is used.
Enough background info – let’s try it out!
Build and run your project, and it should display the same text on the main screen as before, but where’s the Spanish? Now that your app is set up for localization, adding translations is a cinch.