iOS PRogramming 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.
說cultural information ,我們指的是language,currency,date formats ,number formats 等等。
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.
Localization 是提供恰當的數據在你的應用基于用戶的語言,區域設置的過程。
You can find these settings in the Settings application. Select the General row and then the International row.
你可以找到這些信息在你的setting application .選擇general 行,然后是international 行。
Apple makes these processes relatively simple.
apple 盡量讓這個進程更簡單。
An application that takes advantage of the localization APIs does not even need to be recompiled to be distributed in other languages or regions.
一個充分利用了localization APIs的應用甚至不需要重新編譯來發布到另一個國家或地區 。
By the way, "internationalization" and "localization" are long Words. You will sometimes see people abbreviate them to i18n and l10n, respectively.
internationalization 和localization 是長單詞,人們經常縮寫他們分別為i18n和l10n.
1 Internationalization Using NSNumberFormat
NSDateFormatter has a locale property, which is set to the device's current locale.
NSDateFormatter有一個locale property,它會設置為設備現在的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.
無論什么時候你用NSDateFormatter 創建一個date,它會檢查他的locale property 并系相應的設置格式。所以date label 的text在一開始就被設置為國際化了。
NSLocale knows how different regions display symbols, dates, and decimals and whether they use the metric system.
NSLocale知道regions 之間顯示symbols ,dates,decimals 和他們是否使用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.
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?"
當你發送currentLocale 信息給NSLocale時,NSLocale的實例代表了用戶的region setting 。一旦你有了NSLocale的實例,你可以詢問它問題例如"這個region 的currency symbol 是什么""這個region 是否使用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.
為了詢問這些問題中一個,你發送給NSLocale實例消息objectForKey用一個NSLocale 常量作為參數。
NSLocale *locale = [NSLocale currentLocale];
BOOL isMetric = [[locale objectForKey:NSLocaleUsesMetricSystem] boolValue];
NSString *currencySymbol = [locale objectForKey:NSLocaleCurrencySymbol];
?
?
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.
盡管NSLocale 極其強大和有用,總是用她,將使得localizing apps的處理變得非常枯燥。NSNumberFormatter就像NSDateFormmater 對dates.
?
Depending on the locale, the numberAsString may be 123,456.789 or 123 456,789 or some other value.
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSString *numberAsString = [numberFormatter stringFromNumber:@123456.789];
?
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.
使得NSNumberFormatter更有用的是它有能力格式化貨幣的amounts.如果number formatter 的numberStyle屬性設置為NSNumberFormatterCurrencyStyle,它不僅產生相應的組合和小樹分離,而且有currency symbol.
NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
NSString *numberAsString = [currencyFormatter stringFromNumber:@123456.789];
In BNRItemsViewController.m, locate the method tableView:cellForRowAtIndexPath:. Add the static variable currencyFormatter and set its numberStyle to NSNumberFormatterCurrencyStyle.
// Create a number formatter for currency
static NSNumberFormatter *currencyFormatter = nil;
if (currencyFormatter == nil) {
currencyFormatter = [[NSNumberFormatter alloc] init];
currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
}
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.
cell.valueLabel.text = [currencyFormatter?stringFromNumber:@(item.valueInDollars)];
These changes will display the value formatted appropriately for the user's region, with both the number format and currency 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:
為了讓Homepwner更新當region settings 改變時,你需要使用NSNotificationCenter.在BNRItemsViewController's init方法里,注冊locale change notifications .
?
// Register for locale change notifications
[nc addObserver:self
selector:@selector(localeChanged:) name:NSCurrentLocaleDidChangeNotification
object:nil];
?
Add the method localeChanged.
- (void)localeChanged:(NSNotification *)note
{
[self.tableView reloadData];
}
?
2 Localizing Resources 本地化資源
When internationalizing, you ask the instance of NSLocale questions. But the NSLocale only has a few region-specific variables. This is where localization comes into play: Localization is the process by which application-specific substitutions are created for different region and language settings.
當internationalizing,你詢問NSLocale 實例的問題。但是NSLocale 僅僅有一些區域指定的變量。這也是localization怎么玩的。
Localization usually means one of two things:
(1)generating multiple copies of resources like images, sounds, and NIB files for different regions and languages
產生資源的倍數復制:像images,sounds,NIB files在不同的區域和語言。
(2)creating and accessing strings tables to translate text into different languages
創建和獲取string 表來翻譯text 為不同的語言。
Any resource, whether it is an image or a XIB file, can be localized.
任何資源不管它是image還是XIB文件,都能被本地化。
Localizing a resource puts another copy of the resource in the application bundle.
Localizing a resource 把資源的一個拷貝放在了application bundle.
These resources are organized into language- specific directories, known as lproj directories.
這些資源被組織放進language specific directories,稱為lproj directories.
Each one of these directories is the name of the localization suffixed with lproj.
每一個這樣的目錄是以后綴lproj的本地化名字。
For example, the American English localization is en_US: where en is the English language code and US is the United States of America region code. (The region can be omitted if you do not need to make regional distinctions in your resource files.) These language and region codes are standard on all platforms, not just iOS.
例如,American English localization 是en_US.en 是English language code,US 是United Stated 區域code .
When a bundle is asked for the path of a resource file, it first looks at the root level of the bundle for a file of that name. If it does not find one, it looks at the locale and language settings of the device, finds the appropriate lproj directory, and looks for the file there. Thus, just by localizing resource files, your application will automatically load the correct file.
當一個bundle 被詢問資源文件的path,它首先查看bundle 的根層級找到那個名字的文件。如果沒有找到,它會查看locale 和language settings ,找到恰當的lproj 目錄,尋找這個文件。因此,僅僅本地化resource files ,你的應用將自動的加載正確的文件。
One option is to create separate XIB files and to manually edit each string in this XIB file in Xcode. However, this approach does not scale well if you are planning multiple localizations. What happens when you add a new label or button to your localized XIB? You have to add this view to the XIB for every language. This is not fun.
?
To simplify the process of localizing XIB files, Xcode has a feature called Base internationalization. When it is enabled for the project, Base internationalization creates the Base.lproj directory which contains the main XIB files. Localizing individual XIB files can then be done by creating just the Localizable.strings files. It is still possible to create the full XIB files, in case localization cannot be done by changing strings alone. However, with the help of Auto Layout, strings replacement may be sufficient for most localization needs.
為了簡化localizing XIB files的處理,Xcode有一個特性叫做Base internationalization.當它被這個project使用時,Base internationalization 創建了Base.lproj 目錄,它包含了main XIB files .本地化獨特的XIB 文件能夠同故宮創建僅有的Localizable.strings files.這仍然是可能的創建full XIB files ,以防止localization 不能僅僅通過改變strings完成。然而,有Auto layout 的幫助,strings replacement 可能對大多數的localization neees 是足夠的。
In this section, you are going to localize one of Homepwner's interfaces: the BNRDetailViewController.xib file. You will create English and Spanish localizations, which will create two lproj directories, in addition to the base one.
在本節中,你將localize?
BNRDetailViewController.xib文件。你將創建Englsih 和spanish localizations ,這將創建兩個lproj 目錄,除了基礎的那個外。
Normally, you would first enable Base Internationalization in the project Info settings. However, as of this writing, there is a bug in Xcode that will not let you enable that option until at least one XIB file is localized.
一般的,你應該打開Base Internationalization 在project info settings .然而,在Xcode 中有一個bug,不讓你選擇直到一個XIB 文件已經localized .
So, start by localizing a XIB file. Select BNRDetailViewController.xib in the project navigator. Then, show the utility area.
Click the?tab in the inspector selector to open the file inspector. Find the section in this inspector named Localization and click the Localize... button
Select English. This signifies to Xcode that this file can be localized, automatically creates en.lproj, and moves the BNRDetailViewController.xib file to it.
選擇English.這個給Xcode 的信號是這個file能夠被localized,自動的創建en.lproj,將BNRDetailViewController.xib移動到它當中。
Now you need to enable Base Internationalization.Make sure you select the project Homepwner, and not the target Homepwner.
現在你需要使Base Internationalization,確保你選擇了Homepwner工程,而不是target.
In the bottom section of the Info tab of the project, locate the Use Base Internationalization checkbox in the Localizations section and check it. You will see the prompt to select which files will be used to create the Base localization; the table will consist of just BNRDetailViewController.xib and English will be listed as the reference language. Click Finish.
Click the + button under the list of languages and select Spanish. In the dialog, you can uncheck the InfoPlist.strings files and only keep the BNRDetailViewController.xib file checked. Make sure that the reference language is Base and the file type is Localizable Strings. Click Finish. This creates an es.lproj folder and generates the BNRDetailViewController.strings in it that contains all the strings from the base XIB file.
In the project navigator, click the Spanish version of BNRDetailViewController.strings. When this file opens, the text is not in Spanish. You have to translate localized files yourself; Xcode is not that smart.
Edit this file according to the following text. The numbers and order may be different in your file, but you can use the text field in the comment to match up the translations.
當打開BNRDetailViewController.strings文件時,text并不是spanish.你必須轉換localized files 你自己。Xcode 并不是那么聰明。
編輯這個文件根據下面的文字。
3 NSLocalizedString() and Strings Tables ? ?NSLocalizedString和Strings tabels
In many places in your applications, you create NSString instances dynamically or display string literals to the user. To display translated versions of these strings, you must create a strings table.
在許多地方,你動態的創建NSString實例或者展現string literals 給用戶。為了展現這些strings 的翻譯版本,你需要常見一個string table.
A strings table is a file containing a list of key-value pairs for all of the strings that your application uses and their associated translations. It is a resource file that you add to your application, but you do not need to do a lot of work to get data from it.
string table 是一個包含了一列key-value對的所有的strings 你的應用使用或他們相關的翻譯。他是一個資源文件,但是你不需要做更多的事情來獲取這些數據。
?
You might use a string in your code like this:
NSString *greeting = @"Hello!"
To internationalize the string in your code, you replace literal strings with the function NSLocalizedString.
NSString *greeting = NSLocalizedString(@"Hello!", @"The greeting for the user");
This function takes two arguments: a key and a comment that describes the string's use. The key is the lookup value in a strings table. At runtime, NSLocalizedString() will look through the strings tables bundled with your application for a table that matches the user's language settings. Then, in that table, the function gets the translated string that matches the key.
這個函數有兩個參數:key和表述這個string 用途的comment.key 是在strings table 的查找值。在運行是,NSLocalizedString()將查找string tables bundled with 你的應用來找一個匹配用戶語言設置的table.然后在這個table中,函數獲得了匹配這個key的翻譯。
Now you are going to internationalize the string "Homepwner" that is displayed in the navigation bar. In BNRItemsViewController.m, locate the init method and change the line of code that sets the title of the navigationItem.
navItem.title = NSLocalizedString(@"Homepwner", @"Name of application");
?
Two more view controllers contain hard-coded strings that can be internationalized. The toolbar in the BNRDetailViewController shows the asset type. The title of the BNRAssetTypeViewController needs to be updated just like the title of the BNRItemsViewController.
NSString *typeLabel = [self.item.assetType valueForKey:@"label"]; if (!typeLabel) {
typeLabel = @"None";
typeLabel = NSLocalizedString(@"None", @"Type label None"); }
?
self.assetTypeButton.title = [NSString stringWithFormat: NSLocalizedString(@"Type: %@", @"Asset type button"), typeLabel];
?
In BNRAssetTypeViewController.m, update the init method:
if (self) {
self.navigationItem.title = @"Asset Type"; self.navigationItem.title =
NSLocalizedString(@"Asset Type", @"BNRAssetTypeViewController title");
}
return self; }
Once you have files that have been internationalized with the NSLocalizedString function, you can generate strings tables with a command-line application.
一旦你的文件被internationalized 用NSLocalizedString 函數,你能用command-line 應用產生string tables .
Open the Terminal app.
In Terminal, type the following:
cd
followed by a space.?
Next, open Finder and locate BNRItemsViewController.m and the folder that contains it. Drag the icon
of that folder onto the Terminal window. Terminal will fill out the path for you. Press Enter.
?
To generate the strings table, enter the following into Terminal and press Enter:
為了產生string table,輸入如下:
genstrings BNRItemsViewController.m
This creates a file named Localizable.strings in the same directory as BNRItemsViewController.m. Now you need to generate strings from the other two view controllers. Since the file Localizable.strings already exists, you will want to append to it, rather than create it from scratch.
這就會創造出Localizable.string 在和BNRItemViewController.m相同的目錄下?,F在你需要產生從另外兩個view controller.因為Localizable.strings已經存在,你需要append to it 而不是重現創建它。
To do so, enter the following commands in the Terminal (do not forget the -a command line option) and press Enter after each line:
genstrings -a BNRDetailViewController.m
genstrings -a BNRAssetTypeViewController.m
The resulting file Localizable.strings now contains the strings from all three view controllers. Drag from the Finder into the project navigator (or use the Add Files to "Homepwner"... menu item). When the
application is compiled, this resource will be copied into the main bundle.
現在把他們拖動到project navigator中。
/* Name of application */
"Homepwner" = "Homepwner";
?
/* Type Label None */
"None" = "None";
?
/* Assert type button */
"Type:%@" = "Type:%@";
?
Oddly enough, Xcode sometimes has a problem with strings tables. Open the Localizable.strings file in the editor area. If you see a bunch of upside-down question marks, you need to reinterpret this file as Unicode (UTF-16). Show the utility area and select the file inspector. Locate the area named Text Settings and change the pop-up menu next to Text Encoding to Unicode (UTF-16) (Figure 25.10). It will ask if you want to reinterpret or convert. Choose Reinterpret.
Notice that the comment above your string is the second argument you supplied to the NSLocalizedString function. Even though the function does not require the comment argument, including it will make your localizing life easier.
注意到上面的comment是你提供的NSLocalizedString 函數的第二個參數。盡管這個函數不需要comment argument,包含它將使你localizing life 更容易。
Now that you have created Localizable.strings, localize it in Xcode the same way you did the XIB file. Select the file in the project navigator and click the Localize... button in the utility area. Add the Spanish localization and then open the Spanish version of Localizable.strings. The string on the lefthand side is the key that is passed to the NSLocalizedString function, and the string on the righthand side is what is returned. Change the text on the righthand side to the Spanish translation shown below.
現在你創建了Localizable.strings,localize 它在Xcode中。選擇Localize...button。添加Spanish localization 并打開Spanish 版本的LOcalizable.strings.左側是key,右側是你想返回的值。
/* Name of application */
"Homepwner" = "Due?o de casa";
?
/* Type Label None */
"None" = "Nada";
?
/* Assert type button */
"Type:%@" = "Tipo:%@";
?
?
?
?
新聞熱點
疑難解答