iPhone SDK Articles

Sunday, November 16, 2008

Localizing iPhone Apps - Internationalization


By localizing an iPhone app, we display cultural information in the user's specified locale, but what about the text, like the application name and displaying visible information in user's preferred language. In this tutorial, I will show you how we can use resource files to display visible text in user's language.
Introduction
Localization and Internationalization are complimentary activities, with one we can display cultural information like units, dates in the user's preferred locale and the other, let's us display text in the user's preferred language.

The first step is to find out what languages your application is going to support and gather all the text (in different languages), images, videos, sounds and put them in a resource file or in a language directory. To translate text into different languages you can a tool that Google provides here. Even if you do not plan to support different languages in your app, it is a good idea to get it set up front.

The user can change the language by going to Settings -> General -> International -> Language. When the language is changed, the iPhone also changes the name of the application, only if the application supports it.

Preparing for Internationalization
In our sample app, we are going to support two languages English and Italian. Create a new project in Xcode, does not matter what template you select. After you have created your project, open the project location in Finder and create two directories called en.lproj and it.lproj. These two directories become the language project for your application. All the English language resources will stored in the folder en.lproj and the Italian language resources will be stored in it.lproj folder. The resource files that contain the localizable string are called "strings" file and their default name is "Localizable.strings". So, we will create two new strings file in Xcode, select Resources and click on File -> New File -> Other (under Mac OS X) -> Strings file and click on Next, name your file "Localizable.strings" and save it in en.lproj directory. Repeat the same process by saving it in it.lproj directory. This is how the files look like in Xcode, since Xcode is smart enough to figure out that the file is localized for two different languages.

Localizing strings file
Strings are localized in the format "key" = "value";. The key and the value is in double quotes followed by a semi-colon. You can also add comments above every key-value pair, so the resource file is properly documented. Let's add a key-value resource in English and Italian as follows in its own Localizable.strings file

//Localizable.String file for the English version.
"WelcomeKey" = "Welcome!!!";
//Localizable.strings file for the Italian version.
"WelcomeKey" = "Benvenuto!!!";

Let's look at some code on how to get these values from the resource file and display it.

- (void)applicationDidFinishLaunching:(UIApplication *)application {

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
NSString *currentLanguage = [languages objectAtIndex:0];

NSLog(@"Current Locale: %@", [[NSLocale currentLocale] localeIdentifier]);
NSLog(@"Current language: %@", currentLanguage);
NSLog(@"Welcome Text: %@", NSLocalizedString(@"WelcomeKey", @""));

// Override point for customization after application launch
[window makeKeyAndVisible];
}

We get the list of languages by using the key AppleLanguages and then get the first language which is the user's preferred language. We then display some basic information like the locale, language and then display the localized string using NSLocalizedString function, which takes two parameters a key and comment which you can leave it blank. The comment parameter does serve a purpose when we want to generate the strings file automatically. Nowhere in the function we specify, from which language directory we want to display the localized string, it is what we can call language sensitive. If it cannot find the preferred language directory then it picks up second language from the list and so on.

Creating the resource file using genstrings
Using the genstrings tool, we can create the strings file automatically. Be sure to use NSLocalizedString function every where in your code to display the localized text for a given key. When the tool is used on the source files, it will extract all the keys, comments and create a strings file for you, where the comment is set to be the value for the key. All you then have to do is change the value for the keys according to the the language. You can run the command line tool like this to generate "Localizable.strings" file under en.lproj directory.

genstrings -o en.lproj *.m

Before you run the command, make sure the target directory exists.

Localizing iPhone display name
When the user changes its preferred language, the iPhone will also change the display name for all the apps, if it supports that language. Let's see how we can display the app name in Italian, in English our sample app is called "StringsFile". Create new strings file and save it in it.lproj directory, with the name "InfoPlist.strings". Add a new entry with the key "CFBundleDisplayName" without quotes and set the value to "Stringhe di file" (I know not a proper translation, but you get the idea). This is how the file should look like

CFBundleDisplayName = "Stringhe di file";

Now change your preferred language to Italian and the name of your application will be changed. Once you change the language back to English it will say "StringsFile", we do not need to create a new InfoPlist.strings file for English.

Conclusion
Since your iPhone app can be downloaded by anyone in any Country, it becomes extremely important that the app looks and behaves according to the user's locale and language. I hope this tutorial has helped you in localizing your apps.

Happy Programming,
iPhone SDK Articles



Attachments
Suggested Readings


24 comments:

Anonymous said...

thanks a lot

Anonymous said...

Great article, however I just want to point out a problem I had with localising the CFBundleDisplayName. The name of the strings file should be "InfoPlist.strings" not "InfoPList.strings" (notice difference in capitalisation).

Ryan said...

How do you easily localize strings like button names and labels created in the View via NSLocalizedStrings?

Old! said...

Hello, if my Application is not support the language, I Set as the default language?

iPhone SDK Articles said...

Thanks for catching the case error, I made the change.

Happy Programming,
iPhone SDK Articles

iPhone SDK Articles said...

@Ryan why would you want to localize button names? It is not seen by the user, so there is no need to localize them. If you want to localize the button text then you will follow the same steps you take to localize a string.

Happy Programming,
iPhone SDK Articles

iPhone SDK Articles said...

@Old I think there is nothing we can do if the language is not supported by the iPhone. Which language do you want to support?

Happy Programming,
iPhone SDK Articles

Old! said...

Actually I'm doing a game and I would set the language to English if they do not have the language of the appliance, for example the unit is in French, and how my game is not Frances he takes the English language as default

iPhone SDK Articles said...

You do not have to set the language as English, the language is set on the phone. What you have to do is create strings file for the languages you plan to support.

If you want to display units then it is best to use one of the formatters, to learn more formatting data take a look at this article

http://www.iphonesdkarticles.com/2008/11/localizing-iphone-apps-part-1.html

Happy Programming,
iPhone SDK Articles

Old! said...

You do not understand my question.

What I do is the following, I'm doing a game where you have support for English, Portuguese, Spanish, But does not support the French language.

I would like to display the texts in English if no language that supports the device is in

Dave O said...

Dang. This looks really simple but I just can't get it to work. The NSLocalizedString function just returns the @"WelcomeKey" string. currentLanguage is "en" and I have created the en.lproj directory.

iPhone SDK Articles said...

@Dave O Make sure that the case of your key is the same in the strings file and in the code, it can be very sneaky. Double check that you have a directory called en.lproj. If you are still having problems with the app, you can send me an email and I will take a look at it.

Happy Programming,
iPhone SDK Articles

Old! said...

Could solve my problem, we need setar Info.plist file in the default language of development and make sure your file Localizable.strings is in UTF-16

Denis Joseph Barrow said...

Thanks a lot good sir, this topic is not covered in The iphone developers cookbook or iphone open application development.

mkpprod said...

Great tutorial, thank you.. BUT

I have the same problem Dave O has... Only the key name is displayed. So, instead of my custom text, I see "WelcomeKey".

I do not have case issues, and I have followed your steps exactly. In fact, everything works perfectly in the simulator. It wasn't until I ran it on my phone that I started seeing the key name instead of the text.

If you know of something else that needs to be done to get it to work on the phone also, please post it here.. and if possible, shoot me an email directly: barnaclejive AT gmail.

Surender Choudhary said...

hi i also tried the same thing, it is working for me but i have problem in creating Localizable strings folder. I follow the same step that first i create a en.Iproj folder (we can create any where or we have to create in particular folder) then by terminal i move to en.Iproj folder and run the command "genstring -o en.Iproj *.mm" (that will work for mm file also). It is not creating "Localizable.strings" file. We have to put any particular file first in that resources folder
(like - Info.plist
main.m
MainWindow.xib
StringsFile_Prefix.pch
StringsFile.xcodeproj) . Please reply i am waiting......

iPhone SDK Articles said...

@Surender Choudhary

Create the en.lproj folder in the root folder of the project.

You do not have to use genstring tool, you can do it manually which is something I prefer actually. The tool will extract all the keys from your source files and place it under en.lproj folder.

Keys which show up in functions like this
NSLocalizedString(@"WelcomeKey", @"")

So it will extract "WelcomeKey" and place it under en.lproj folder. The name of the file will be called Localizable.strings file.

I hope this helps

Happy Programming,
iPhone SDK Articles

Surender Choudhary said...

Thanks for the reply, now its working for me.

It is working for English but i tried same thing for other languages like sp,it etc, it is not working. It is displaying alerts from en(Localizable.string)file. It is not dsipalying alert from any other file like sp or it. can you please help me out.

iPhone SDK Articles said...

@Surender Choudhary

Sure send me an email at iphonearticles [@] gmaildotcom and I will be happy to take a look at it.

Happy Programming,
iPhone SDK Articles

Surender Choudhary said...

Thanks for the reply again, now that is working i removed all the files are cerated freshly. i have another problem when i install on device (3G iPhone), it is displaying in English not in 'it' (Native setting is 'it'). Can you please help me out.

Thanks,
Surender

Anonymous said...

Is it possible to change the language inside the application without having effect to general language settings?

iPhone SDK Articles said...

@Anonymous The only way to do that is to allow the user to change language from the app and then you have to somehow fake that the language is changed and display different text/views based on the language selected.

Hope this helps.

Happy Programming,
iPhone SDK Articles

Brian Dunagan said...

That's really neat! I didn't realized the genstrings command existed. I wrote up an article on ibtool that complements your article: http://www.bdunagan.com/2009/03/15/ibtool-localization-made-easy/

Anonymous said...

Question, I have an app that is localized for 7 languages. However, when I submit it to the app store, the only language that shows up under languages is English. Any ideas how to get the other languages to show up? I noticed a localization field in the plist but it only allows me to select 1 language?