Be Swift: Localization and Internationalization

Overview:

With a global app market, it only makes sense to develop apps that operate in native languages with sensitivity to their cultures. Apple has provided developers with a rich set of tools, features, and functionality to support well over a hundred different world languages.

At first, the problem seems simple – just replace the text with a language-specific version. Instead of defining the text that gets displayed as hard-coded strings within the software, the text for each language/region is defined in a separate strings file. A method call within the software references the correct text string within the strings file. A language-specific strings file within each app is selected (if the app supports language localization) by setting the language for the iPhone or iPad device in the device ‘Language & Region’ option under ‘General’ within ‘Settings’.

Even with all the support structure that is in place, providing a native language and cultural app experience is amazingly complex with a mind-numbing set of details to consider and resolve:

  • Singularity and plurality of things
  • Dates and calendars
  • Currency symbols and formatting
  • Numbers and formats
  • Alphabets and punctuation
  • Reading direction
  • Gender assignment to things
  • Sorting a list
  • Keyboards

And, that doesn’t even begin to consider the accuracy of translations and relevant context. Some of the complexity of getting localization and internationalization correct is humorously presented by Tom Scott in the video at the top of this post.

Tips and Best Practices:

I am using the following design guidelines and practices to enable localization and globalization for apps. Many of these guidelines and practices are not my own, but a collection of best practices from other developers.

  • Start with the code and configuration setup from the start. It is so much harder to retrofit an app design and the software code.
  • Use separate localized strings for singular and plural nouns. Various languages implement singular and plural differently.
  • Use flexible and autosizing of localized fields since the length or width will vary between languages.
  • Localize the title of the app that displays under the icon.
  • Use NSDateFormatter when displaying dates. Use NSNumberFormatter when displaying numbers. Pass NSLocale currentLocale into NSDateFormatter and NSNumberFormatter.
  • Use a namespace approach. With a large number of individual items to be converted to various languages, it is crucial to develop at the start a naming convention that will be consistent throughout the software code. For example:
NSLocalizedString(@"aboutscreen.title.welcome", @"comment about context")

Configuring for Localization and Internationalization:

Project configuration to support localization and internationalization for the mobile device family (iPhone, iPad) and the Mac are slightly different. As such, each are separately described.

There are three sets of language-specific files to configure for localization and internationalization within Xcode.

First set of files (language-specific ‘Info.plist’):

  • Click on ‘info.plist’ file located in the Project Navigator pane which will show its contents in the Editor Pane. Within the Utility pane, click on ‘Localize…’ button. Xcode prompts with a question about localization. Select ‘Base’ and click on ‘Localize’.
  • To add languages and regions to the project, select the project (e.g., Hobbies) in the Project Navigator pane, then select ‘Project’ in the Editor pane as shown below. Within the ‘Localizations’ section under the ‘Info’ tab, verify that ‘Use Base Internationalization’ is checked and select ‘+’ for adding new languages.
localize_01
  • An initial list of 33 languages is shown when the ‘+’ button is selected. At the bottom of this list is the option ‘Other’ to display over a hundred more language/region options. It is absolutely amazing in extent – pick a language, any language! Then, click on ‘Finish’ to add the language. Note that a localized ‘info.plist’ will be added under ‘Info.plist’ in the Project Navigator pane. Repeat this step to configure the project for additional languages.
localize_02
  • Initially, I added French, German, and Chinese to the localized languages for this prototype app for test purposes only. I know a little French, the German language is a good test for autolayout, and Chinese is a good choice for testing the app with a symbol-based language. The intent is that any app deployed by Champlin Technologies LLC support many languages.

Second set of files (language-specific ‘Localizable.strings’):

  • At this point, a second set of files, known as ‘Localizable.strings’, is created for the project. Each of these files contains the translated strings for one of the localized languages. From File > New > File, select the Resource category under iOS and select the File >’Strings File’ and click ‘Next’. Name the file File >’Localizable.strings’, select File >’Supporting Files’ location from File >’Group’, and click on File >’Create’.
  • The resulting File >’Localizable.strings’ file is placed under File >’Supporting Files’ in the Project Navigator pane. Before localizing this file for the other project languages, I added a representative line for translated text as shown.
localize_03

  • Clicking the Localize… button at this point creates the additional ‘Localizable.strings’ files for the other selected languages. Xcode prompts with a question about localization. Select ‘Base’ and click on ‘Localize’. A checkbox for each of the localized languages now appears within the Localization section in the Utilities pane. As each checkbox is checked, another ‘Localizable.strings’ file is created as shown.
localize_04

  • For each language, select the appropriate ‘Localizable.strings’ file and replace the base text with the translations. For the representative example for this tutorial, the “Welcome!” message is replaced with the translated version in each of the ‘Localizable.strings’ files, respectively.
"mainScreen.title.welcome" = "Welcome!";
"mainScreen.title.welcome" = "Bienvenue!";
"mainScreen.title.welcome" = "Herzlich Willkommen!";
"mainScreen.title.welcome" = "欢迎";

Third set of files (language-specific ‘InfoPlist.strings’):

  • A third set of files, known as ‘InfoPlist.strings’, is created for the project. Each of these files contains the translated strings that are used for the app title that appears under the app icon on the iPhone or iPad home screen. From File > New > File, select the Resource category under iOS and select the ‘Strings File’ and click ‘Next’. Name the file ‘InfoPlist.strings’, select File >’Supporting Files’ location from File >’Group’, and click on File >’Create’.
  • The resulting ‘infoPlist.strings’ file is placed under File >’Supporting Files’ in the Project Navigator pane. Before localizing this file for the other project languages, I added the two lines for providing localized app titles as shown.
"CFBundleDisplayName" = "Hobby";
"CFBundleName" = "Hobby";
  • Clicking the Localize… button at this point creates the additional ‘InfoPlist.strings’ files for the other selected languages. Xcode prompts with a question about localization. Select ‘Base’ and click on ‘Localize’. A checkbox for each of the localized languages now appears within the File >’Localization’ section in the Utilities pane. As each checkbox is checked, another ‘InfoPlist.strings’ file is created as shown.

localize_05

  • For each language, select the appropriate ‘InfoPlist.strings’ file and replace the base text with the translations.

Creating the localized strings:

After support for localization and internationalization has been configured for a Xcode project, the NSLocalizedString method provides the basic interface for text strings that are translated by the text in the ‘Localizable.strings’ file. In Swift, NSLocalizedString method has the following format:

NSLocalizedString(key:tableName:bundle:value:comment:)

An example NSLocalizedString method is shown below:

NSLocalizedString("mainscreen.title.welcome", comment: "welcome message on initial main screen")
For the Mac, there are four sets of language specific files to configure an Xcode project for localization and internationalization. The extra set of files are associated with the ‘MainMenu.xib’ file.

First two sets of files (language-specific ‘Info.plist’ and ‘MainMenu.strings’):

  • Click on Info.plist file located in the Project Navigator pane which will show its contents in the Editor Pane. Within the Utility pane, click on ‘Localize…’ button. Xcode prompts with a question about localization. Select ‘Base’ and click on ‘Localize’.
  • To add languages and regions to the project, select the project (e.g., Hobbies) in the Project Navigator pane, then select ‘Project’ in the Editor pane as shown below. Within the ‘Localizations’ section under the ‘Info’ tab, verify that ‘Use Base Internationalization’ is checked and select ‘+’ for adding new languages.
  • An initial list of 33 languages is shown when the ‘+’ button is selected. At the bottom of this list is the option ‘Other’ to display over a hundred more language/region options. After selecting a language, click on ‘Finish’ to add the language. Note that a localized ‘Info.plist’ file and a localized ‘MainMenu.strings’ file is added in the Project Navigator pane. Repeat this step to configure the project for additional languages.
localize_06

Third set of files (language-specific ‘Localizable.strings’):

  • At this point, a third set of files, known as ‘Localizable.strings’, is created for the project. Each of these files contains the translated strings for one of the localized languages. From File > New > File, select the Resource category under Mac and select the File >’Strings File’ and click File >’Next’. Name the file File >’Localizable.strings’, select File >’Supporting Files’ location from File >’Group’, and click on File >’Create’.
  • The resulting File >’Localizable.strings’ file is added in the Project Navigator pane. Before localizing this file for the other project languages, I added a representative line for translated text.
  • Clicking the Localize… button at this point will create the additional ‘Localizable.strings’ files for the other selected languages. Xcode prompts with a question about localization. Select ‘Base’ and click on ‘Localize’. A checkbox for each of the localized languages now appears within the Localization section in the Utilities pane. As each checkbox is checked, another ‘Localizable.strings’ file is created.
  • For each language, select the appropriate ‘Localizable.strings’ file and replace the base text with the translations. For the representative example for this tutorial, the “Welcome!” message is replaced with the translated version in each of the ‘Localizable.strings’ files, respectively.
"mainWindow.title.welcome" = "Welcome!";
"mainWindow.title.welcome" = "Bienvenue!";
"mainWindow.title.welcome" = "Herzlich Willkommen!";
"mainWindow.title.welcome" = "欢迎";

Fourth set of files (language-specific ‘InfoPlist.strings’):

  • A fourth set of files, known as ‘InfoPlist.strings’, contains the translated strings that are used for the app title that appears above the app icon when highlighted on the Mac home home screen. From File > New > File, select the Resource category under Mac and select the ‘Strings File’ and click ‘Next’. Name the file ‘InfoPlist.strings’, select File >’Supporting Files’ location from File >’Group’, and click on File >’Create’.
  • The resulting ‘InfoPlist.strings’ file is added in the Project Navigator pane. Before localizing this file for the other project languages, I added the two lines for providing localized app titles as shown.
"CFBundleDisplayName" = "Hobby";
"CFBundleName" = "Hobby";
  • Clicking the Localize… button at this point will create the additional ‘InfoPlist.strings’ files for the other selected languages. Xcode prompts with a question about localization. Select ‘Base’ and click on ‘Localize’. A checkbox for each of the localized languages now appears within the File >’Localization’ section in the Utilities pane. As each checkbox is checked, another ‘infoPlist.strings’ file is created.
  • For each language, select the appropriate ‘InfoPlist.strings’ file and replace the base text with the translations.
  • The screenshot below shows the four sets of files that are generated to provide localization and internationalization on the Mac.
localize_07

Creating the localized strings:

After support for localization and internationalization has been configured for a Xcode project, the NSLocalizedString method provides the basic interface for text strings that are translated by the text in the ‘Localizable.strings’ file. In Swift, NSLocalizedString method has the following format:

NSLocalizedString(key:tableName:bundle:value:comment:)

An example NSLocalizedString method is shown below

NSLocalizedString("mainWindow.title.welcome", comment: "welcome message on initial window")

Testing Localizations:

Following a user’s approach to manualy selecting their language on an iPhone or iPad (e.g., Settings app > General > Languages & Region) is not conducive to testing an app in development for two reasons:

  • Lots of manual steps to change the language.
  • The language change affects all localizable apps on the device including all text within File >’Settings’ confounding the ability to make subsequent changes.

Creating a set of selectable arguments that can be passed on launch as part of the Xcode runtime configuration is a more versatile app testing approach that works with either the device simulator or an actual iPhone/iPad device seamlessly. There are at least three ways to access the screen to create and select arguments to be passed on launch:

  • From the Xcode menu: select ‘Product > Scheme > Edit Scheme …
  • From an Xcode shortcut key: ⌘ ⇧ <
  • From an Xcode toolbar: click on the app target, then select ‘Edit Scheme …‘ from the dropdown menu

localize_08

On the left side of the panel, select ‘Run‘ and select ‘Arguments Passed On Launch‘ as shown.

localize_09

Create a set of arguments, one for each language/region. I have included four examples: English, French, German, and simplified Chinese. Any selected argument passed at launch from this list will override the current value in NSUserDefaults for the duration of app execution from Xcode. Therefore, by selecting one language/region at a time from this list will change the localization for the app for testing without changing any other app’s localization.

Summary:

To add localization and internationalization to an app takes extra effort and requires a healthy attention to detail. And, that is why I identify with the following quote:

“NSLocalizedString is a remarkably reliable indicator of code quality. Those who care enough to take a few extra seconds to internationalize are very likely to be just as thoughtful when it comes to design and implementation.”

Mattt Thompson

Reference Material:

Internationalization and Localization Guide

Internationalization and Localization of Apps in Xcode6 and Swift

NSHipster: NSLocale

String Localization

Internationalization Tutorial for iOS

Working with Localization in iOS 8 and Xcode 6

Using Launch Arguments to Test Localizations

Launch Arguments and Environment Variables

Working with Localization

2017-08-07T14:02:42+00:00 By |Swift, Xcode App Dev|1 Comment

One Comment

  1. RedLeader8 August 2, 2017 at 1:50 pm - Reply

    Nice post about the complexity of localization and internationalization.

Leave A Comment