Search
Follow
Recent Comments

Entries in localization (5)

Tuesday
May102011

Localizing NIB files with Xcode 4

One problem I have with Xcode 4 is that there are lots of tiny icons and tabs whose purpose is not immediately obvious. Also the UI has undergone a radical overhaul so knowing how to do something with Xcode 3 is not always much of a help when you want to do the same thing with Xcode 4. This means that the first time you try to do something you spend a few minutes hunting around for the right button to press.

One example of this is when you want to localize a NIB file. With Xcode 3 you right-clicked on the NIB file and managed the localizations in the file info dialog window. Unfortuantely Xcode 3 made a mess of handling the naming of the locales (see Xcode localization frustrations). With Xcode 4 things are a little different.

Localizing a NIB file

The action of localizing a NIB file is pretty easy once you know where to look in Xcode 4. Now that Interface Builder is integrated into Xcode you need to look in the right-hand utility pane with the NIB you want to localize selected:

To display the localization option you need to ensure you have selected the first tab in the utility pane by selecting the file inspector icon:

Adding new languages is then as easy as clicking the “+” button in the localization section of the inspector. A nice touch here is that frequently used languages are grouped at the top along with an Add all button which speeds things up. The menu also lists all locales by their user-readable names (e.g. German) together with the ISO language designator (e.g. de) so you no longer have to hunt around for the correct codes.

As you add each language Xcode creates the appropriate project directory and copies the NIB file into the directory. The directory names now also use the short country codes so in the following example:

The project ends up with directories named en.lproj, es.lproj, fr.lproj and it.lproj and everything finally works as expected. Of course, at this point you have to do the hard work of actually localizing all of the strings in the NIB file…

Friday
Dec172010

Localizing iPhone App Settings Strings

I covered in a previous post how to localise the name of an iPhone application as it appears under the icon on the iPhone home screen and in the Settings application when the app has a settings bundle. So I just wanted to finish up the topic by covering how to localize the strings that are used within the settings bundle.

Localizing Strings

First a recap. Usually with an iOS or mac OS X project when you want to localize some text that is embedded in your code you add a Localizable.strings file for each locale that you want to support. The way I usually do that is to start by adding a file named Localizable.strings to my project resources and populate it with the strings for the default English locale. Then using the Info dialog window for the file I select Make File Localizable and add the languages I want to support.

What happens when you localize a file in this way is that you end up with a set of directories, one for each locale, with a name of the form <locale>.lproj in your application bundle. So for example if you add a Spanish locale Xcode creates a directory named es.lproj for you. Each directory then contains the set of files specific for that locale.

The Settings Bundle

The difference when working with strings in a settings bundle is that the localization needs to happen inside the settings bundle and not the application bundle. If you look at the Settings.bundle file in the Xcode navigator you will see that it is created with an en.proj directory containing a strings file for the English locale. This makes it easier to prepare the bundle for adding other locales.

Our Root.plist file which contains the configuration settings looks like this:

Notice the first entry that specifies the name of the strings filename (Root). There is only one string in this case that we want to localize which is the title of the toggle switch which has the value “Example switch”. Looking at the Root.strings file for the English (en) locale we see the usual key-value pair:

“Example switch” = “Example switch”;

 

Not very exciting in this case since the key and its value have the same value which is the title of the switch. So the next step is to add some additional locales. The easiest way I have found to do that is to open the settings bundle with the Finder. You should find the Settings.bundle file at the top level of the project directory but you can also navigate to it from Xcode by right-clicking on the Settings.bundle in Xcode and selecting “Reveal in Finder”.

Once you have the file selected in the Finder, right-click and select “Show Package Contents”. The contents of the settings bundle will then be visible in the finder at which point you can create additional directories for each locale you want to add. In the example below I have added es.lproj and it.lproj directories for the Spanish and Italian locales. I also copied the Root.strings file from the en.lproj directory to these new directories.

Once you have added the directories to the settings bundle they should show up in Xcode under the Settings.bundle entry (you may need to open and close the directory hierarchy to get it to refresh).

At this point it is simple to edit the Root.strings file for each locale. The Spanish and Italian versions of the file finish up as follows:

Root.strings (es locale)

“Example switch” = “Ejemplo”;

 

Root.strings (it locale)

“Example switch” = “Esempio”;

 

If you build and run the project and check the Settings app you should see that the title for the switch changes when you change the language settings of the device (Settings -> General -> International -> Language). So here it is first in Spanish:

and now in Italian

Wrapping Up

If you want to take a look at the example app that I used for this short series of posts on localization you can find it here.

Thursday
Dec162010

Localizing iPhone App Icon is not supported

one additional comment I meant to add to the post yesterday about localising an iPhone application name was about the application icon. You might expect that you could localize the application icon by including the CFBundleIconFile or CFBundleIconFiles keys in the InfoPlist.strings file for each supported locale. Unfortunately it does work and as far as I know there is no way to actually make it work with iOS 4.2.

Until yesterday though I was never totally sure it was not possible. Then I spotted this thread in the Apple developer forums. There is a post by Bill Dudney, author of the excellent iPhone SDK Development book from Pragmatic Programmers and now an Apple employee. Bill confirms that localizing the application icon is not currently supported and suggests raising an enhancement request.

So in the meantime you may want to choose an application icon that will work for all regions and languages where you expect the app to be used…

Wednesday
Dec152010

Localize iPhone Application Name

Some time ago I wrote a post about adding a settings bundle to an iPhone App that received a number of questions about how to change the application name that is shown under the icon on the iPhone home screen and in the settings application. So I thought I would finally get around to showing how you can use the localization capabilities of iOS to change the application name. I will cover localizing the strings inside a settings bundle in a follow up post.

CFBundleDisplayName

The steps to localise the application name are actually very simple but like many things with iOS it can take some hunting around to fully understand what you need to do. The secret is to localise the value of the CFBundleDisplayName key contained in an applications Information Property List (Info.plist) file. The Apple documentation for this key is as follows:

CFBundleDisplayName (String - iOS, Mac OS X) specifies the display name of the bundle. If you support localized names for your bundle, include this key in both your information property list file and in the InfoPlist.strings files of your language subdirectories. If you localize this key, you should also include a localized version of the CFBundleName key.

If you do not intend to localize your bundle, do not include this key in your Info.plist file. Inclusion of this key does not affect the display of the bundle name but does incur a performance penalty to search for localized versions of this key.

Before displaying a localized name for your bundle, the Finder compares the value of this key against the actual name of your bundle in the file system. If the two names match, the Finder proceeds to display the localized name from the appropriateInfoPlist.strings file of your bundle. If the names do not match, the Finder displays the file-system name.

By default when you create an iOS application Xcode populates a default Info.plist file with values for both the CFBundleDisplayName (“Bundle display name”) and the CFBundleName (“Bundle name”) keys. By default these keys are both set to ${PRODUCT_NAME} which is set to the name used when creating the project. You do NOT need to change these keys in the Info.plist file.

InfoPlist.strings

To localize the value of an Info.plist key we need to add an InfoPlist.strings file to the project. We can do that in the usual way by right-clicking on the Resources group and selecting “Add -> New File…” and choosing the Strings file template from the Mac OS X Resource section (for some reason the Strings file template is not included in the iOS Resource section). Give the new file the name InfoPlist.strings and ensure it is added to the current target:

Before we localise the file we can add the default values for the English locale. We will add values for both the CFBundleDisplayName and CFBundleName keys though for iOS the important one is the bundle display name:

“CFBundleDisplayName” = “Hello”;

“CFBundleName” = “Hello”;


Our example app is named Hello in the English locale. To localise the file, right-click on it and select “Get Info” to open the file info window and click the “Make File Localizable” button at the bottom of the dialog:

On the General tab of the Localized dialog there is a button to “Add Localization” that we can use to add each of the required locales. For the purposes of this example I will add “en” (English), “it” (Italian) and “es” (Spanish) locales. (For a discussion on the Xcode issues around the use of “en” and “English” locales see this post on Xcode localization frustrations.)

Once all the locales have been added the dialog should look like this:

The InfoPlist.strings file in the Xcode Groups & Files window should now expand into a list of files named for each locale.

We can now modify each of these language specific versions to set the application name for each locale. So the version for the “it” locale now becomes:

“CFBundleDisplayName” = “Ciao”;

“CFBundleName” = “Ciao”;


Likewise the version for the “es” locale is modified as follows:

“CFBundleDisplayName” = “Hola”;

“CFBundleName” = “Hola”;


Build and Run

To test it out we just need to build and run the app in the simulator and change the language settings (Settings -> General -> International -> Language). Setting the language to “Italiano” changes the name to “Ciao” both under the icon, the settings application and when searching for the app:

If we change the language to “Español” the name changes to “Hola”:

Setting the language back to English resets the application name to “Hello”.

Wrapping Up

You can find the example app that demonstrates how to customise the application name here. I will cover how to localize the strings inside a settings bundle in a follow up post.

Saturday
Apr102010

Xcode localization frustrations 

Xcode does a lot to make it easy to localize project resources such as strings and NIB files. There is one small annoyance that is worth being aware of though if you want to maintain your sanity. Since Max OS X 10.4 the preferred way to identify a language is with the ISO language designations. To be precise the two letter codes as defined by ISO 639-1 should be used where possible. So English is identified by “en”, Spanish by “es”, French by “fr”, etc.

Prior to Max OS X 10.4 the legacy (but more user-readable) names such as “English”, “Spanish”, etc., were used but the Apple internationalization documentation now makes it clear that these values are deprecated:

In addition to the ISO language designators, the bundle routines also recognize several legacy language designators. These designators let you specify a language by a user-readable name, instead of by a two or three character code. Designators included names such as English, French, German, Japanese, Chinese, Spanish, Italian, Swedish, and Portuguese among others. Although these names are still recognized and processed by the NSBundle class and Core Foundation bundle functions, their use is deprecated and support for them in future versions of Mac OS X or iPhone OS is not guaranteed. Use the codes described in “Language Designations” and “Regional Designations” instead.

To localize a NIB file in Xcode you simply use the “Make File Localizable” button in the General tab after right-clicking on the NIB and selecting Get Info. The NIB file starts out with an “English” localization by default but you can easily add new localizations using the Add Localization button at the bottom. Each time you add a localization a copy of the NIB file is created in a folder named <language>.lproj.

So if you have been following along at this point you might add localizations for “fr”, “es” and maybe even “en”. This works fine until you have the good idea to delete the legacy English localization file. At this point if you try to add a new language nothing happens. The new language file is not created and no error message is generated. Of course if you happen to be adding the new language at some future date it may not be immediately obvious what is going wrong.

The only way I have found to recover from this situation is to delete all of the localizations from Xcode and start again (copy the existing files to a safe location first). As long as you leave the “English” language localization everything works correctly even if you also have an “en” language.

Since Apple started deprecating the legacy identifiers in 10.4 I think it is about time they updated Xcode or at least included an error message to give you a hint as to why it is failing. Having said that I guess they have more important developments to be working on at the moment…