iOS internationalization from day one

A few days ago we did a private beta release of the Babatuba Collage App. Here’s the map from the first 72 hours:

Babatuba!

Babatuba was to be international from day one, this decision fundamentally directed the product. Many aspects of an application change as a function of your audience’s locality. Sina Weibo is popular in China but not in the United States. Bandwidth varies wildly from nation to nation: we increased image compression to speed up loading times in China. We found the avg. bandwidth by country in the Akamai State of the Internet useful. Ideally this would be calculated individually using bandwidth data on the phone.

Separating code and data is good engineering practice; don’t litter your code with literals, internationalize!

Here’s a 5-minute tutorial & example iOS Project:

iOS Internationalization in 5 minutes

Step 1. Use NSLocalizedString for all string constants

If you use the C pre-processor macro NSlocalizedString, which is defined as #define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil], you can use the shell script below to generate the body of the .strings file that you will use in the next step. Example:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.labelIntl.text = NSLocalizedString(@"LABEL_TEXT", nil);
    [self.buttonBabatuba setTitle:NSLocalizedString(@"BUTTON_TITLE", nil) 
                         forState:UIControlStateNormal];
}

Step 2. Set up a Localized.strings file & Localize your InfoPlist.strings

Create a Localizable.strings file: File >> New >> File >> iOS >> Resource >> Strings. Select the new file and click Localize.

Strings File
Localize iOS
Localizable.strings

Use the following shell script (included in the example project) to generate the boilerplate for all localizable string in your project:

#!/bin/sh
grep -hor "NSLocalizedString(\@.*)" . | sed s/NSLocalizedString\(@// |
     sed s/,.*$// | uniq | sort | sed 's/$/ = "";/'

This will generate the body of your Localizable.strings file. To set the name of your app as it appears on the springboard, localize your InfoPlist.strings file and add this to each file:

"CFBundleDisplayName" = "$LOCALIZED_NAME";
"CFBundleName" = "$LOCALIZED_NAME";

Step 3. Rejoice!

Just translate the .strings files and you’re set! Kind of ^^. App usage will vary from culture to culture, you will need to localize your product’s features based on usage. However, that’s up to you and your team’s understanding of your target market! You can get the full iOS internationalization example project on GitHub.

There are other great tutorials for Apple’s Internationalization APIs online:

In the mean time, you can participate in the Babatuba beta for just 99¢! It’s been internationalized for English, Spanish, and Chinese (both Simplified and Traditional).

Participate in the Babatuba Beta for iOS

  • @nicklockwood on twitter brings up two good points:

    1) An alternative method is to internationalize using storyboards (I prefer to do it programatically). The relevant command is ibtool –export-strings-file stooryboard.strings *.storyboard

    2) Genstrings is very similar to the sell script above, the main difference is that mine writes to stdout instead of clobbering a file on disk. It’s slightly more UNIXy.

  • Angel

    Even easier is to use AGi18n tools