88bifa必发唯一官网国际化与当地化

国际化确保你的本土信息不是硬编码进你的应用,一个程序或软件在支持国际化的基础上

88bifa必发唯一官网 12

iOS Programming Localization 本地化,ioslocalization

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 行。

88bifa必发唯一官网 1

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

88bifa必发唯一官网 2

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 88bifa必发唯一官网 3tab
in the inspector selector to open the file inspector. Find the section
in this inspector named Localization and click the Localize… button

88bifa必发唯一官网 4

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.

88bifa必发唯一官网 5

88bifa必发唯一官网 6

88bifa必发唯一官网 7

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.

88bifa必发唯一官网 8

88bifa必发唯一官网 9

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.

 

88bifa必发唯一官网 10

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相同的目录下。现在你需要产生从另外两个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.

88bifa必发唯一官网 11

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:%@”;

 

 

 

 

Programming Localization
本地化,ioslocalization iOS Programming Localization 本地化
Internationalization is making sure your native cultural information is
not hard-cod…

参考资料

Internationalization and Localization
Guide

简介

国际化(internationalisation,i18n):一个程序或软件可给特定的人群使用而无须修改或重新编译源代码。对于
iOS 来说就是,使App能够适用于不同的语言,地区,文化的过程。

本地化
(localisation,l10n)
:一个程序或软件在支持国际化的基础上,给定程序特定区域的语言信息使其在信息的输入输出等处理上适应特定区域人群的使用。对于
iOS 来说就是,将App的内容翻译为多种语言的过程。

总的来说,国际化是开发者的任务,是一个一般化的过程;而本地化则是翻译者所做的事情,是一个具体的过程。国际化的运作为本地化工作提供了可能。一个软件的国际化实现需要本地化的支持。

用户设置对于国际化的影响

在 iOS
设置应用中的通用->语言与地区中可以分别设置语言,地区和日历。一个支持国际化的应用会根据语言的设置选择相应的本地化包,语言的改变会导致系统重新启动,以便所有应用重新应用新的语言设置。地区主要影响日期,时间,数字,货币等数据的格式。用户可以通过日历选择不同的历法。地区和日历的设置都是即时的,不需要重新启动系统。另外,在语言与地区中还可以设置首选语言顺序列表,应用会以此为依据选择本地化语言包(按顺序找第一个应用支持的本地化语言包)。

使应用支持国际化

使用Base Internationalization国际化界面文本

从Xcode5之后,工程默认支持Base Internationalization。
Base
Internationalization将界面文本与.storyboard和.xib文件分离,使得项目只需要一套.storyboard和.xib文件。在.storyboard和.xib文件中使用你设置的开发语言填写界面文本,这套.storyboard和.xib文件就叫做Base
Internationalization。之后在本地化时,将以开发语言为资源翻译成多种语言,这些语言以.strings格式的文本文件对应相应的.storyboard和.xib文件。

一般情况下,每种语言相对应的文件会放在相应的语言包下,比如en.lproj、zh.lproj等。但是所有的.storyboard和.xib文件会放在一个名为Base.lproj的文件夹内,这就是为了共用同一套.storyboard和.xib文件,这样,在其他语言包内就可以只存放相应的.strings格式的文本文件了。由于.storyboard和.xib文件中已经使用开发语言填写了界面文本,所以在开发语言的语言包内就不需要再有相对应的.strings文件了。
关于开发语言的设置:

  1. 在项目的.xcodeproj文件中打开project.pbxproj
  2. 搜索developmentRegion,并将该key的值改为所要设置的开发语言对应的语言ID,比如en、zh等
  3. 保存,效果如下图所示
![](https://upload-images.jianshu.io/upload_images/669609-0c93dab4f79fd5ae.png)
使用Auto Layout辅助国际化界面文本

因为所支持的语言所占界面空间不同,Auto
Layout可以使一套界面适配布局不同的文字。使用时注意:

  1. 显示文字的组件不使用固定宽度的约束,否则在某些语言下文字可能显示不完全,text
    fields和labels默认的行为都是自动适配到内容的合适的尺寸,完全可以使用这种方式。
  2. 添加水平间距约束时,使用leading和trailing,这样针对左右顺序不同的语言可互换左右间距值。
  3. 因为语言不同视图组件所占空间不同,所以约束应于相邻视图组件建立,这样当语言改变时,其他视图组件也会自动适配。
国际化代码中的文本

在项目中,一些在界面上显示的文本是需要在代码中提供的(比如错误信息提示),而对这部分文本国际化的方式是将文本写入.strings文件中,之后使用宏NSLocalizedString去从文件中获取。在.strings文件中键值对的格式为

"key1" = "value1";
"key2" = "value2";

使用NSLocalizedString去取值的方式为

NSLocalizedString("key1", "comment");
NSLocalizedStringFromTable("key1", "tableName", "comment");

其中标准的NSLocalizedString函数会从main
bundle中的Localizable.strings文件中找到相应键的值,而comment是对该键值对的解释。同理NSLocalizedStringFromTable函数的第二个参数可以指定其他.strings文件的文件名。

国际化数据格式

不同的国家和地区有着不同的日期,时间,货币,数值等的格式,所以要在代码中根据用户设置的地区来正确的格式化这些数据。
格式化时用到NSLocale类,NSLocale类封装了某一个地区的相应的格式化信息,如果要获得用户当前设置地区的NSLocale实例可以使用[NSLocale currentLocale]或者[NSLocale autoupdatingCurrentLocale],两者的区别是,后一个类方法返回的值会根据用户设置的改变而改变,而前者不会。可以通过NSLocal查看很多这一地区的数据格式化信息,例如(其他key值请查阅相关文档):

NSNumber *metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem];
NSString *currencySymbol = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
// 用当前地区的语言显示语言ID
NSLocale *zhHansLocal = [NSLocale localeWithLocaleIdentifier:@"zh-Hans"];
NSString *currentLocalZH = [zhHansLocal displayNameForKey:NSLocaleIdentifier value:@"zh-Hant-TW"];
NSString *currentLocalEN = [zhHansLocal displayNameForKey:NSLocaleIdentifier value:@"en-US"];
// 获取该地区所使用的引号
NSString *bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];
NSString *eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
// 国际化大小写转换
NSString *localizedUppercaseString = [string uppercaseStringWithLocale:[NSLocale currentLocale]];
NSString *localizedlowercaseString = [string lowercaseStringWithLocale:[NSLocale currentLocale]];
NSString *localizedCapitalizedString = [string capitalizedStringWithLocale:[NSLocale currentLocale]];

当使用[NSString stringWithFormat]去拼装字符串时,如果传入的参数带有数值,日期等需要格式化的内容,最好使用以下方式(更好的方式是使用formatter进行转换):

// 使[NSLocale systemLocale]
NSString *localizedString = [NSString localizedStringWithFormat:@"%3.2f", myNumber];
NSString *localizedString = [[NSString alloc] initWithFormat:@"%@" locale:[NSLocale localeWithLocaleIdentifier:@"zh"], [NSDate date]];

使用formatter格式化日期和时间时的国际化

// 使用预设的格式
NSString *localizedDateTime = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterShortStyle];
// 使用自定义的格式
NSDateFormatter *dateFormatter = [NSDateFormatter new];
NSString *localeFormatString = [NSDateFormatter dateFormatFromTemplate:@"dMMM" options:0 locale:dateFormatter.locale];
dateFormatter.dateFormat = localeFormatString;
NSString *localizedString = [dateFormatter stringFromDate:[NSDate date]];

对于数值型数据的格式化主要包括小数、千位分割、货币、百分比。同样也需要支持国际化。

NSString *localizedString = [NSNumberFormatter localizedStringFromNumber:myNumber numberStyle:NSNumberFormatterDecimalStyle];

同理对于NSCalendar的使用也受NSLocale的影响。
地区和时区的设置发生变化的通知分别是NSCurrentLocaleDidChangeNotificationNSSystemTimeZoneDidChangeNotification

国际化支持相反的语言方向

有一些语言,比如阿拉伯语等,方向是从右向左的。使用
Base Internationalization和Auto
Layout在大部分情况下可以很好的支持这些语言,一些不支持的情况,可以在代码中进行如下判断:

if ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:view.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft) {
    …
}

本地化应用

当我们使应用支持国际化后,就可以配合翻译人员完成应用本地化的工作了。大致的过程是,通过
Xcode 将开发语言的文本资源导出为 XLIFF (XML Localisation Interchange
File
Format)
文件,翻译人员在完成该文件内的相应翻译内容后,再通过 Xcode
将文件导入,这时所翻译的语言资源就会被加入到工程中了。

导出 XLIFF
  1. 在 Xcode 中选中工程或 target。
  2. 选择 Editor > Export For Localization。

之后 Xcode 会将 .xliff 文件导出到你指定的目录中。如果你在工程的
Localizations 设置项中还没有添加过其他的语言,而只有开发语言(如
English)一种,那么导出的文件为 en.xliff。这时的 en.xliff
文件中并没有指明要翻译的目标语言,而这会导致在翻译完成后文件无法正常导入,需要在文件源码中添加target-language=""字段。更好的做法是,在创建工程时就把要从开发语言翻译的其他语言(如
Chinese)添加到 Localizations 中,这样导出的文件就为
zh.xliff,且其中已标明目标语言,可以正常的导入。另一个要注意的地方是,.strings文件支持国际化时,开始的开发语言版本不要放到Base.lproj文件夹中,Base.lproj文件夹中存放的全部是界面文件,而是应直接放入对应的开发语言的.lproj文件中。

命令行方式:

xcodebuild -exportLocalizations -localizationPath <dirpath> -project <projectname> [[-exportLanguage <targetlanguage>]]

在等待翻译资源的时候,你并不希望界面或者仅仅是界面中的文本再发生变化,这个时候可以使用
Xcode 的一项特性 Locking Views。可以只针对某一 view 修改,在该 view 的
Identity inspector 中修改 Lock 项。也可设置整个 nib
文件的该属性,选中对应 nib 文件后,修改 Editor > Localization Locking
菜单项。

导入 XLIFF
  1. 在 Xcode 中选中工程或 target。
  2. 选择 Editor > Import Localizations。

Xcode 会从 XLIFF 文件中解析出翻译内容的 .strings
文件,然后放到对应语言的 .lproj 目录中,而在工程中,nib 文件和 .strings
文件都以组的形式管理。

命令行方式:

xcodebuild -importLocalizations -localizationPath <filepath> -project <projectname>
其他资源

除了文本资源外,其他的资源文件,比如图片、音视频文件等可能也需要针对不同地区使用不同内容。

88bifa必发唯一官网 12

在国际化资源文件后,就可以将本地化版本的文件加到对应的 .lproj 目录中。

最佳实践

对于大部分的国内开发者来说,其应用主要针对使用中文的用户,而鉴于翻译资源的有限,可能针对其他地区用户仅能支持国际通用的英文。在这种情况下,最合适的流程是,在开发过程中,开发者使用中文填写界面文本,而之后由翻译人员翻译为英文,最后使应用在所有不匹配中文地区的设备上,都能使用英文资源。

要达到上述效果,首先要设置工程的开发语言为中文,如上文所述,修改工程文件中的字段
developmentRegion 为
zh,同时确保需要翻译的英文已添加在列表中。在完成国际化的工作后,就可导出
en.xliff 文件交由翻译人员翻译,并最终导入。最后一步,是要确认 Info.plist
文件中的 CFBundleDevelopmentRegion 字段设置为
en,该字段决定在用户当前地区未匹配到翻译资源时,使用应用已有的哪一套翻译资源作为界面文本显示。

需要注意的一点是,尽管文档中提到:

You can choose from more than 100 different languages and dialects
designated by regions to localize your app. However, the more general
you make your localized resources, the more regions you can support
with a single set of resources. This can save a lot of space in your
app bundle and help reduce localization costs. For example, if you
don’t need to distinguish between different regions that use the
English language, you can add English to support users in the United
States, United Kingdom, and Australia. Even if you provide
region-specific resources always provide a complete set of
language-specific resources for all the languages you support.

但当用户设备的语言设置为繁体中文时,并不会匹配到中文(zh)的语言资源,所以在上述配置后,最终在繁体中文的设备上,应用会使用英文资源。如果想要所有中文设备都显示作为开发语言的简体中文,最后需要多添加一种语言
zh-Hant,但不需要进一步翻译,直接以开发语言为模板生成即可。

测试

在 Xcode
中,可以使用预览功能,在不运行应用的情况下,检测国际化和本地化的结果。选择一个
.storyboard 或 .xib 文件,打开辅助编辑器,在相关文件中选择
Preview,通过右下角语言选项,可以在国际化后选择 Double-Length
Pseudolocalizations 进行检测,本地化后选择对应语言进行检测。

预览过后,可以通过设置应用启动时的参数,在设备上测试国际化和本地化的结果,而不需要修改设备的设置。编辑
Scheme,选择 Run -> Options,在 Application Language
一项中,可以选择对应语言资源,Double-Length Pseudolocalizations 以及
Right to Left Pseudolocalizations。勾选 Show non-localized strings
项,可以检测未本地化的文本,其会以大写形式显示。