25
Localization

The appeal of iOS is global – iOS users live in many different countries and speak many different languages. You can ensure that your application is ready for this global audience through the processes of internationalization and localization. Internationalization is making sure your native cultural information is not hard-coded into your application. (By cultural information, we mean language, currency, date formats, number formats, and more.)

Localization, on the other hand, is the process of providing the appropriate data in your application based on the user’s Language and Region Format settings. You can find these settings in the Settings application. Select the General row and then the International row.

Figure 25.1  International settings

International settings

Apple makes these processes relatively simple. An application that takes advantage of the localization APIs does not even need to be recompiled to be distributed in other languages or regions. In this chapter, you are going to localize the item detail view of Homepwner. (By the way, internationalization and localization are long words. You will sometimes see people abbreviate them to i18n and l10n, respectively.)

Internationalization Using NSNumberFormat

In this first section, you will use the class NSNumberFormat to internationalize the number format and currency symbol for the value of an item.

Did you know that Homepwner is already partially internationalized? Launch the application and add a new item. The date label in the BNRDetailViewController is formatted according to the current regional settings. In the US, the dates are displayed as Month Day, Year. Cancel adding a new item.

Now open the Settings application and change Region Format to United Kingdom (GeneralInternationalRegion Format). Switch back to Homepwner and add a new item again. This time, the date is displayed as Day Month Year. The text for the date label has already been internationalized. When did this happen?

Figure 25.2  Date format: US vs UK

Date format: US vs UK

In Chapter 10, you used an instance of NSDateFormatter to set the text of the date label of BNRDetailViewController. NSDateFormatter has a locale property, which is set to the device’s current locale. Whenever you use an NSDateFormatter to create a date, it checks its locale property and sets the format accordingly. So the text of the date label has been internationalized from the start.

NSLocale knows how different regions display symbols, dates, and decimals and whether they use the metric system. An instance of NSLocale represents one region’s settings for these variables. In the Settings application, the user can choose a region, like United States or United Kingdom. (Why does Apple use region instead of country? Some countries have more than one region with different settings. Scroll through the options in Region Format to see for yourself.)

When you send the message currentLocale to NSLocale, the instance of NSLocale that represents the user’s region setting is returned. Once you have that instance of NSLocale, you can ask it questions like, What is the currency symbol for this region? or Does this region use the metric system?

To ask one of these questions, you send the NSLocale instance the message objectForKey: with one of the NSLocale constants as an argument. (You can find all of these constants in the NSLocale documentation page.)

N​S​L​o​c​a​l​e​ ​*​l​o​c​a​l​e​ ​=​ ​[​N​S​L​o​c​a​l​e​ ​c​u​r​r​e​n​t​L​o​c​a​l​e​]​;​
B​O​O​L​ ​i​s​M​e​t​r​i​c​ ​=​ ​[​[​l​o​c​a​l​e​ ​o​b​j​e​c​t​F​o​r​K​e​y​:​N​S​L​o​c​a​l​e​U​s​e​s​M​e​t​r​i​c​S​y​s​t​e​m​]​ ​b​o​o​l​V​a​l​u​e​]​;​
N​S​S​t​r​i​n​g​ ​*​c​u​r​r​e​n​c​y​S​y​m​b​o​l​ ​=​ ​[​l​o​c​a​l​e​ ​o​b​j​e​c​t​F​o​r​K​e​y​:​N​S​L​o​c​a​l​e​C​u​r​r​e​n​c​y​S​y​m​b​o​l​]​;​

Let’s internationalize the value amount displayed in each BNRItemCell. Open Homepwner.xcodeproj.

While NSLocale is extremely powerful and useful, always using it directly would make the process of localizing apps very tedious. That's why you used NSDateFormatter earlier. There is another class, NSNumberFormatter that does for numbers what NSDateFormatter does for dates. For example, to format a number appropriately for the current locale, use the stringFromNumber: method. Depending on the locale, the numberAsString may be 123,456.789 or 123 456,789 or some other value.

N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​*​n​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​=​ ​[​[​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​
N​S​S​t​r​i​n​g​ ​*​n​u​m​b​e​r​A​s​S​t​r​i​n​g​ ​=​ ​[​n​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​s​t​r​i​n​g​F​r​o​m​N​u​m​b​e​r​:​@​1​2​3​4​5​6​.​7​8​9​]​;​

What makes NSNumberFormatter even more useful is its capability to format currency amounts. If the number formatter's numberStyle property is set to NSNumberFormatterCurrencyStyle, it will start producing the numbers formatted not only with the appropriate group and decimal separators, but also with the currency symbol. (In some countries, numbers may be formatted differently for currency and non-currency purposes.)

N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​*​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​ ​[​[​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​
c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​.​n​u​m​b​e​r​S​t​y​l​e​ ​=​ ​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​C​u​r​r​e​n​c​y​S​t​y​l​e​;​
N​S​S​t​r​i​n​g​ ​*​n​u​m​b​e​r​A​s​S​t​r​i​n​g​ ​=​ ​[​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​s​t​r​i​n​g​F​r​o​m​N​u​m​b​e​r​:​@​1​2​3​4​5​6​.​7​8​9​]​;​

In BNRItemsViewController.m, locate the method tableView:cellForRowAtIndexPath:. Add the static variable currencyFormatter and set its numberStyle to NSNumberFormatterCurrencyStyle.

 ​ ​ ​ ​c​e​l​l​.​s​e​r​i​a​l​N​u​m​b​e​r​L​a​b​e​l​.​t​e​x​t​ ​=​ ​i​t​e​m​.​s​e​r​i​a​l​N​u​m​b​e​r​;​
 ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​a​ ​n​u​m​b​e​r​ ​f​o​r​m​a​t​t​e​r​ ​f​o​r​ ​c​u​r​r​e​n​c​y​
 ​ ​ ​ ​s​t​a​t​i​c​ ​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​*​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​ ​n​i​l​;​
 ​ ​ ​ ​i​f​ ​(​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​=​ ​n​i​l​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​ ​[​[​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​.​n​u​m​b​e​r​S​t​y​l​e​ ​=​ ​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​C​u​r​r​e​n​c​y​S​t​y​l​e​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​c​e​l​l​.​v​a​l​u​e​L​a​b​e​l​.​t​e​x​t​ ​=​ ​[​N​S​S​t​r​i​n​g​ ​s​t​r​i​n​g​W​i​t​h​F​o​r​m​a​t​:​@​"​$​%​d​"​,​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​i​t​e​m​.​v​a​l​u​e​I​n​D​o​l​l​a​r​s​]​;​

When the text of the cell’s valueLabel is set in this method, the string "$%d" is used, which makes the currency symbol always a dollar sign. Use the currencyFormatter to format the amount correctly.

 ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​a​ ​n​u​m​b​e​r​ ​f​o​r​m​a​t​t​e​r​ ​f​o​r​ ​c​u​r​r​e​n​c​y​
 ​ ​ ​ ​s​t​a​t​i​c​ ​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​*​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​ ​n​i​l​;​
 ​ ​ ​ ​i​f​ ​(​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​=​ ​n​i​l​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​ ​=​ ​[​[​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​.​n​u​m​b​e​r​S​t​y​l​e​ ​=​ ​N​S​N​u​m​b​e​r​F​o​r​m​a​t​t​e​r​C​u​r​r​e​n​c​y​S​t​y​l​e​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​c​e​l​l​.​v​a​l​u​e​L​a​b​e​l​.​t​e​x​t​ ​=​ ​[​N​S​S​t​r​i​n​g​ ​s​t​r​i​n​g​W​i​t​h​F​o​r​m​a​t​:​@​"​$​%​d​"​,​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​i​t​e​m​.​v​a​l​u​e​I​n​D​o​l​l​a​r​s​]​;​
 ​ ​ ​ ​c​e​l​l​.​v​a​l​u​e​L​a​b​e​l​.​t​e​x​t​ ​=​ ​[​c​u​r​r​e​n​c​y​F​o​r​m​a​t​t​e​r​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​s​t​r​i​n​g​F​r​o​m​N​u​m​b​e​r​:​@​(​i​t​e​m​.​v​a​l​u​e​I​n​D​o​l​l​a​r​s​)​]​;​

 ​ ​ ​ ​c​e​l​l​.​t​h​u​m​b​n​a​i​l​V​i​e​w​.​i​m​a​g​e​ ​=​ ​i​t​e​m​.​t​h​u​m​b​n​a​i​l​;​

These changes will display the value formatted appropriately for the user’s region, with both the number format and currency symbol.

Build and run the application. You will see the value amount formatted according to the currently selected region, which should be United Kingdom if you followed the instructions at the beginning of this section. In the Settings application, change Region Format back to United States (GeneralInternationalRegion Format). Return to Homepwner.

You were probably expecting to see values displayed in dollars ($). However, it did not happen. To trigger the update to the table view, start adding a new item and immediately cancel. Now, you will see the values formatted correctly, because viewWillAppear: was called and it reloaded the table view. (Note that this is not a currency conversion; you are just replacing the symbol.)

To make Homepwner update when the region settings change, you need to use NSNotificationCenter. In BNRItemsViewController’s init method, register for locale change notifications:

 ​ ​ ​ ​ ​ ​ ​ ​N​S​N​o​t​i​f​i​c​a​t​i​o​n​C​e​n​t​e​r​ ​*​n​c​ ​=​ ​[​N​S​N​o​t​i​f​i​c​a​t​i​o​n​C​e​n​t​e​r​ ​d​e​f​a​u​l​t​C​e​n​t​e​r​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​[​n​c​ ​a​d​d​O​b​s​e​r​v​e​r​:​s​e​l​f​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​s​e​l​e​c​t​o​r​:​@​s​e​l​e​c​t​o​r​(​u​p​d​a​t​e​T​a​b​l​e​V​i​e​w​F​o​r​D​y​n​a​m​i​c​T​y​p​e​S​i​z​e​)​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​n​a​m​e​:​U​I​C​o​n​t​e​n​t​S​i​z​e​C​a​t​e​g​o​r​y​D​i​d​C​h​a​n​g​e​N​o​t​i​f​i​c​a​t​i​o​n​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​:​n​i​l​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​R​e​g​i​s​t​e​r​ ​f​o​r​ ​l​o​c​a​l​e​ ​c​h​a​n​g​e​ ​n​o​t​i​f​i​c​a​t​i​o​n​s​
 ​ ​ ​ ​ ​ ​ ​ ​[​n​c​ ​a​d​d​O​b​s​e​r​v​e​r​:​s​e​l​f​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​s​e​l​e​c​t​o​r​:​@​s​e​l​e​c​t​o​r​(​l​o​c​a​l​e​C​h​a​n​g​e​d​:​)​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​n​a​m​e​:​N​S​C​u​r​r​e​n​t​L​o​c​a​l​e​D​i​d​C​h​a​n​g​e​N​o​t​i​f​i​c​a​t​i​o​n​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​:​n​i​l​]​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​s​e​l​f​;​

Add the method localeChanged.


-​ ​(​v​o​i​d​)​l​o​c​a​l​e​C​h​a​n​g​e​d​:​(​N​S​N​o​t​i​f​i​c​a​t​i​o​n​ ​*​)​n​o​t​e​
{​
 ​ ​ ​ ​[​s​e​l​f​.​t​a​b​l​e​V​i​e​w​ ​r​e​l​o​a​d​D​a​t​a​]​;​
}​

Build and run the application. Now, when you change the regional settings and return to Homepwner, the table view will be reloaded and the value label will display the amount properly formatted. To see why you used the number formatter instead of just retrieving the currency symbol, change the region to Germany. Not only did the currency symbol change, but also a few other things: the position of the currency symbol (after the number, instead of before), spacing (one space between the amount and the currency symbol, instead of no spaces), decimal mark (a comma instead of a dot), and thousands separator (a dot instead of a comma).

Figure 25.3  Number format: US vs UK vs Germany

Number format: US vs UK vs Germany
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset