xib相关(二十) —— UINib之字符串资源(五)

版本记录

版本号 时间
V1.0 2018.05.07

前言

iOS中的视图加载可以有两种方式,一种是通过xib加载,另外一种就是通过纯代码加载。它们各有优点和好处,xib比较直观简单,代码比较灵活但是看着很多很乱,上一家公司主要风格就是用纯代码,这一家用的就是xib用的比较多。这几篇我们就详细的介绍一个xib相关知识。感兴趣的可以看上面写的几篇。
1. xib相关(一) —— 基本知识(一)
2. xib相关(二) —— 文件冲突问题(一)
3. xib相关(三) —— xib右侧标签介绍(一)
4. xib相关(四) —— 连线问题(一)
5. xib相关(五) —— 利用layout进行约束之界面(一)
6. xib相关(六) —— 利用layout进行约束之说明和注意事项(二)
7. xib相关(七) —— Storyboard中的segue (一)
8. xib相关(八) —— Size Classes(一)
9. xib相关(九) —— 几个IB修饰符(一)
10. xib相关(十) —— xib的国际化(一)
11. xib相关(十一) —— xib的高冷用法之修改视图的圆角半径、边框宽度和颜色(一)
12. xib相关(十二) —— UIStackView之基本介绍(一)
13. xib相关(十三) —— UIStackView之枚举UIStackViewDistribution使用(二)
14. xib相关(十四) —— UIStackView之UIStackViewAlignment使用(三)
15. xib相关(十五) —— UIStackView之工程实践(四)
16. xib相关(十六) —— UINib之基本介绍(一)
17. xib相关(十七) —— UINib之Introduction(二)
18. xib相关(十八) —— UINib之Nib文件(三)
19. xib相关(十九) —— UINib之Nib文件(四)

回顾

上一篇主要讲述了UINib之Nib文件,这一篇讲述字符串资源。


String Resources - 字符串资源

本地化过程的一个重要部分是本地化您的应用程序显示的所有文本字符串。根据它们的性质,位于nib文件中的字符串可以很容易地与nib文件内容的其余部分一起定位。但是,嵌入代码中的字符串必须被提取,本地化,然后重新插入代码。为了简化这一过程并简化维护代码,OS X和iOS提供了将字符串与代码分离并将它们放入资源文件中这种基础结构,以便轻松进行本地化。

包含可本地化字符串的资源文件由于文件扩展名为.strings,因此称为字符串文件。您可以根据需要手动或编程创建字符串文件。标准字符串文件格式由一个或多个键值对和可选注释组成。给定对中的键和值是用双引号括起来并用等号分隔的文本字符串。 (您也可以使用字符串文件的属性列表格式,在这种情况下,顶级节点是一个字典,并且该字典的每个键值对都是一个字符串条目。)

Listing 2-1显示了一个简单的字符串文件,其中包含默认语言的非本地化条目。当你需要显示一个字符串时,你将左边的字符串传递给一个可用的字符串加载例程。你得到的是包含最适合当前用户的文本翻译的匹配值字符串。对于开发语言,通常对键和值使用相同的字符串,但这样做不是必需的。

Listing 2-1  A simple strings file

/* Insert Element menu item */
"Insert Element" = "Insert Element";
/* Error string used for unknown error types. */
"ErrorString_1" = "An unknown error occurred.";

一个典型的应用程序每个本地化至少有一个字符串文件,也就是每个包的.lproj子目录中的一个字符串文件。默认字符串文件的名称是Localizable.strings,但您可以使用您选择的任何文件名创建字符串文件。创建字符串文件在Creating Strings Resource Files中有更深入的讨论。

注意:建议您使用UTF-8编码保存字符串文件,该编码是标准字符串文件的默认编码。当Xcode将字符串文件复制到产品中时,会自动将字符串文件从UTF-8转换为UTF-16。有关标准字符串文件格式的更多信息,请参阅Creating Strings Resource Files。有关Unicode及其文本编码的更多信息,请转至 http://www.unicode.org/ or http://en.wikipedia.org/wiki/Unicode

字符串资源(本地化和非本地化)的加载最终依赖于OS X和iOS中的bundle和国际化支持。有关bundle的信息,请参阅 Bundle Programming Guide。有关国际化和本地化的更多信息,请参阅Internationalization and Localization Guide


Creating Strings Resource Files - 创建字符串资源文件

虽然您可以手动创建字符串文件,但很少需要这样做。 如果使用适当的字符串加载宏编写代码,则可以使用genstrings命令行工具来提取这些字符串并为您创建字符串文件。

以下各节介绍如何设置源文件以促进使用genstrings工具的过程。 有关该工具的详细信息,请参阅genstrings手册页。

1. Choosing Which Strings to Localize - 选择本地化哪些字符串

当涉及到本地化应用程序的接口时,并不总是适用于本地化您的应用程序使用的每个字符串。 翻译是一个昂贵的过程,翻译用户从未看到的字符串是浪费时间和金钱。 不显示给用户的字符串(例如应用程序内部使用的通知名称)不需要翻译。 考虑下面的例子:

if (CFStringHasPrefix(value, CFSTR("-")) {    CFArrayAppendValue(myArray, value);};

在这个例子中,字符串“ - ”在内部使用,用户永远不会看到; 因此,它不需要放在一个字符串文件中。

以下代码显示了用户看不到的另一个字符串示例。 字符串%d%d%s不需要本地化,因为用户永远不会看到它,并且它对用户看到的任何内容都没有影响。

matches = sscanf(s, "%d %d %s", &first, &last, &other);

由于nib文件是分开定位的,因此不需要包含已位于nib文件内部的字符串。 但是,您应该本地化的一些字符串包括以下内容:

  • 以编程方式添加到窗口,面板,视图或控件并随后显示给用户的字符串。 这包括您传入标准例程的字符串,例如显示警告框的字符串。
  • 菜单项标题字符串,如果这些字符串以编程方式添加。 例如,如果您使用自定义字符串作为撤消菜单项,那些字符串应该位于字符串文件中。
  • 显示给用户的错误消息。
  • 显示给用户的任何样板文字。
  • 应用程序的信息属性列表(Info.plist)文件中的一些字符串; 请参阅Runtime Configuration Guidelines*。
  • 新的文件和文件名称。

2. About the String-Loading Macros - 关于字符串加载宏

Foundation and Core Foundation框架定义了下面的加载宏,使从字符串文件中加载字符串更容易:

您可以在源代码中使用这些宏来从应用程序的某个字符串文件中加载字符串。 在检索实际字符串值时,宏将用户的当前语言偏好设置考虑在内。 另外,genstrings工具搜索这些宏,并使用它们包含的信息为应用程序构建最初的一组字符串文件。

有关如何使用这些宏的其他信息,请参阅Loading String Resources Into Your Code

3. Using the genstrings Tool to Create Strings Files - 使用genstrings工具产生字符串文件

在开发过程中的某个时候,您需要通过代码创建所需的字符串文件。如果您使用Core Foundation和Foundation宏编写代码,则创建字符串文件的最简单方法是使用genstrings命令行工具。您可以使用此工具生成一组新的字符串文件或根据您的源代码更新一组现有文件。

要使用genstrings工具,通常至少要提供两个参数:

  • 源文件列表
  • 一个可选的输出目录

genstrings工具可以用.c,.m或.java文件扩展名解析C,Objective-C和Java代码文件。虽然不是严格要求,但建议指定输出目录,并且是genstrings放置结果字符串文件的位置。在大多数情况下,您需要为开发语言指定包含项目资源的目录。

以下示例显示了一个用于运行genstrings工具的简单命令。此命令使工具解析当前目录中的所有Objective-C源文件,并将生成的字符串文件放入必须已存在的en.lproj子目录中。

genstrings -o en.lproj *.m

第一次运行genstrings工具时,它会为您创建一组新的字符串文件。后续运行将使用源代码中的当前字符串条目替换这些字符串文件的内容。对于后续运行,在运行genstrings之前保存当前字符串文件的副本是个好主意。然后,您可以区分新旧版本,以确定哪些字符串已添加到(或已更改)您的项目。然后,您可以使用此信息来更新字符串文件的任何已经本地化的版本,而不是替换这些文件并再次对其进行本地化。

在单个字符串文件中,每个key必须是唯一的。幸运的是,genstrings工具足够智能,可以合并找到的任何重复条目。当它发现在单个字符串文件中多次使用的密钥字符串时,该工具会将各个条目的注释合并为一个注释字符串并生成警告。 (可以使用-q选项禁止重复条目警告。)如果将相同的key字符串分配给不同字符串文件中的字符串,则不会生成警告。

有关使用genstrings工具的更多信息,请参阅genstrings手册页。

4. Creating Strings Files Manually - 手动创建字符串文件

虽然genstrings工具是创建字符串文件最方便的方法,但您也可以手动创建它们。要手动创建字符串文件,请在TextEdit(或您的首选文本编辑应用程序)中创建一个新文件,并使用Unicode UTF-8编码保存它。 (在保存文件时,TextEdit通常默认选择合适的编码方式。要强制执行特定编码,必须在应用程序首选项中更改保存选项。)此文件的内容由一组键值对和可选注释组成描述每个键值对的目的。键和值字符串由等号分隔,整个条目必须以分号字符结尾。按照惯例,注释被包含在C风格的注释分隔符(/ /)中,并且被放置在它们描述的条目之前。

Listing 2-2显示了字符串文件的基本格式。本示例中的条目来自TextEdit应用程序的Localizable.strings文件的英文版本。每个等号左侧的字符串表示该键,右侧的字符串表示该值。开发应用程序时的一个常见约定是使用等于用于开发应用程序的语言中的值的key名称。因此,因为TextEdit是使用英语开发的,所以Localizable.strings文件的英文版具有匹配的键和值。

Listing 2-2  Strings localized for English

/* Menu item to make the current document plain text */
"Make Plain Text" = "Make Plain Text";
/* Menu item to make the current document rich text */
"Make Rich Text" = "Make Rich Text";

Listing 2-3显示了相同条目的德语翻译。 这些条目也位于名为Localizable.strings的文件中,但该文件版本位于TextEdit应用程序的德语项目目录中。 请注意,这些键仍然是英语,但分配给这些键的值是德语。 这是因为最终用户从不会看到关键字符串。 它们被代码用来检索相应的值字符串,在这个例子下,它是德语的。

Listing 2-3  Strings localized for German

/* Menu item to make the current document plain text */
"Make Plain Text" = "In reinen Text umwandeln";
/* Menu item to make the current document rich text */
"Make Rich Text" = "In formatierten Text umwandeln"

5. Detecting Non-localizable Strings - 检测非本地字符串

基于AppKit的应用程序可以利用内置的支持来检测不需要本地化的字符串,以及那些需要本地化但目前不需要的字符串。要使用此内置支持,请在运行应用程序时设置用户默认值或添加启动参数。指定一个布尔值来指示是启用还是禁用用户默认值。可用的用户默认值如下:

  • NSShowNonLocalizableStrings用户默认标识不可本地化的字符串。字符串以大写形式记录到shell中。此选项偶尔会产生一些误报,但总体上仍然有用。
  • NSShowNonLocalizedStrings用户默认定位的字符串是本地化的,但在应用程序的现有字符串文件中找不到。您可以使用此用户默认值来捕获过时的本地化问题。

例如,要在TextEdit应用程序中使用NSShowNonLocalizedStrings用户默认值,请在终端中输入以下内容:

/Applications/TextEdit.app/Contents/MacOS/TextEdit -NSShowNonLocalizedStrings YES

Loading String Resources Into Your Code - 加载字符串资源到代码中

Core FoundationFoundation框架提供了用于检索存储在字符串文件中的本地化和非本地化字符串的宏。 尽管这些宏的主要目的是在运行时加载字符串,但它们还可以充当次要目的,作为genstrings工具可用于定位应用程序的字符串资源的标记。 这是第二个目的,它解释了为什么许多宏允许您指定比加载字符串通常需要更多的信息。 genstrings工具使用您提供的信息自动创建或更新应用程序的字符串文件。 表2-1列出了可以为这些例程指定的信息类型,并描述了如何使用genstrings工具使用该信息。

Table 2-1 Common parameters found in string-loading routines

参数 描述
Key 该字符串用于查找相应的值。 该字符串不得包含扩展ASCII字符集中的任何字符,其中包括ASCII字符的重音版本。 如果您希望初始值字符串包含扩展的ASCII字符,请使用允许您指定默认值参数的例程。 (有关扩展ASCII字符集的信息,请参阅相应的Wikipedia entry。)
Table name 指定key所在的字符串文件的名称。 genstrings工具将此参数解释为字符串应放置在其中的字符串文件的名称。 如果未提供表名,则字符串将放置在默认的Localizable.strings文件中。 (为此参数指定一个值时,请包含不带.strings扩展名的文件名。)表名以.nocache结尾的.strings文件(例如ErrorNames.nocache.strings)不会通过NSBundle缓存其内容。
Default value 与给定键相关联的默认值。 如果未指定默认值,那么genstrings工具将使用key字符串作为初始值。 默认值字符串可能包含扩展的ASCII字符。
Comment 翻译注释以包含字符串。 您可以使用注释向翻译团队提供有关如何使用给定字符串的线索。 genstrings工具将这些注释放入字符串文件中,并将它们放在相关条目正上方的C风格注释分隔符(/ /)中。
Bundle 与包含字符串文件的包相对应的NSBundle对象或CFBundleRef类型。 您可以使用它从不同于应用程序主包的包中加载字符串。 例如,您可以使用它从框架或插件加载本地化的字符串。

当您从字符串文件请求字符串时,返回的字符串取决于可用的本地化(如果有)。 Cocoa和Core Foundation宏使用内置的bundle国际化支持来检索其本地化符合用户当前语言首选项的字符串。 只要您的本地化资源文件放置在适当的特定于语言的项目目录中,使用这些宏加载字符串应自动生成适当的字符串。 如果找不到适当的本地化字符串资源,则该包的加载代码会自动选择相应的非本地化字符串。

有关一般国际化以及如何创建特定于语言的项目目录的信息,请参阅Internationalization and Localization Guide。 有关bundle结构以及如何从bundle目录中选择资源文件的信息,请参阅Bundle Programming Guide

1. Using the Core Foundation Framework - 使用Core Foundation框架

Core Foundation框架定义了一个函数和几个宏,用于从应用程序包中加载本地化的字符串。NSBundle类的localizedStringForKey:value:table:方法从驻留在当前包中的字符串文件加载指定的字符串资源。 Cocoa还定义了以下用于获取本地化字符串的宏:

与Core Foundation一样,Apple建议您使用Cocoa便捷宏来加载字符串。 这些宏的主要优点是它们可以被genstrings工具解析并用于创建应用程序的字符串文件。 他们使用起来也更简单,并让您将翻译评论与每个条目相关联。

有关前面宏的语法的信息,请参阅Foundation Functions Reference。 用于加载字符串的其他方法也在NSBundle Class Reference中定义。

2. Examples of Getting Strings - 获取字符串示例

以下示例演示了使用Foundation和Core Foundation宏来检索字符串的基本技巧。 每个示例都假定当前包中包含名称为Custom.strings的字符串文件,该文件已被翻译成法文。 该翻译文件包含以下字符串:

/* A comment */
"Yes" = "Oui";
"The same text in English" = "Le même texte en anglais";

使用Foundation框架,你可以您可以使用NSLocalizedStringFromTable宏来获取“YES”字符串的值,如以下示例所示:

NSString* theString;
theString = NSLocalizedStringFromTable (@"Yes", @"Custom", @"A comment");

使用Core Foundation框架,您可以使用CFCopyLocalizedStringFromTable宏获取相同的字符串,如下例所示:

CFStringRef theString;
theString = CFCopyLocalizedStringFromTable(CFSTR("Yes"), CFSTR("Custom"), "A comment");

在这两个示例中,代码指定要检索的key,即字符串“YES”。 它们还指定要在其中查找key的字符串文件(或表),在本例中为Custom.strings文件。 在字符串检索期间,注释字符串被忽略。


Advanced Strings File Tips - 高级字符串文件提示

以下各节提供了一些关于使用字符串文件和字符串资源的高级技巧。

1. Searching for Custom Functions With genstrings - 使用genstrings搜索自定义函数

genstrings工具默认情况下搜索Core FoundationFoundation字符串宏。它使用这些宏中的信息在项目的字符串文件中创建字符串条目。您还可以指导genstrings在您的代码中查找自定义的字符串加载函数,并使用除标准宏之外的那些函数。您可以使用自定义函数来封装内置的字符串加载例程并执行一些额外的处理,或者您可以用您自己的自定义模型替换默认的字符串处理行为。

如果要使用自定义函数使用genstrings,则函数必须使用Foundation宏使用的命名和格式约定。您的函数的参数必须完全匹配相应宏的参数。当你调用genstrings时,你需要指定-s选项,后跟与NSLocalizedString宏对应的函数的名称。您的其他函数名称应该从这个基本名称构建。例如,如果你指定的函数名称MyStringFunction,你的其他函数名应该是MyStringFunctionFromTableMyStringFunctionFromTableInBundleMyStringFunctionWithDefaultValuegenstrings工具查找这些函数并使用它们来构建相应的字符串文件。

2. Formatting String Resources - 格式化字符串资源

对于某些字符串,您可能不希望(或能够)对字符串资源中的整个字符串进行编码,因为部分字符串可能在运行时发生更改。 例如,如果一个字符串包含用户文档的名称,则需要能够将该文档名称动态插入到字符串中。 创建字符串资源时,可以使用通常用于处理Foundation和Core Foundation框架中的字符串替换的任何格式化字符。 Listing 2-4显示了几个使用基本格式化字符的字符串资源。

Listing 2-4  Strings with formatting characters

"Windows must have at least %d columns and %d rows." =
"Les fenêtres doivent être composes au minimum de %d colonnes et %d lignes.";
"File %@ not found." = "Le fichier %@ n’existe pas.";

要用实际值替换格式化字符,可以使用字符串资源作为格式字符串,使用NSString的stringWithFormat:方法或CFStringCreateWithFormat函数。 Foundation和Core Foundation支持printf语句中使用的大多数标准格式化字符。另外,可以使用前面示例中显示的%@说明符来插入与任意Objective-C对象关联的描述性文本。请参阅String Programming Guide中的Formatting String Objects以获取说明符的完整列表。

翻译过程中经常出现的一个问题是,翻译者可能需要对翻译后的字符串中的参数进行重新排序,以解决源语言和目标语言的差异。如果一个字符串包含多个参数,那么翻译器可以在格式化字符之间插入n $格式的特殊标签(其中n指定原始参数的位置)。这些标签让翻译器重新排列出现在原始字符串中的参数。以下示例显示了一个字符串,其两个参数在翻译的字符串中被反转:

/* Message in alert dialog when something fails */
"%@ Error! %@ failed!" = "%2$@ blah blah, %1$@ blah!";

3. Using Special Characters in String Resources - 在字符串资源中使用特殊字符

就像在C中一样,一些字符必须以反斜杠作为前缀,然后才能将它们包含在字符串中。 这些字符包括双引号,反斜杠字符本身以及特殊控制字符,如换行符(\ n)和回车符(\ r)。

"File \"%@\" cannot be opened" = " ... ";
"Type \"OK\" when done" = " ... ";

您可以通过指定\ U随后最多四个十六进制数字,将任意Unicode字符包含在值字符串中。 四位数字表示所需的Unicode字符的条目; 例如,空格字符由十六进制20表示,因此当指定为Unicode字符时将是\ U0020。 如果字符串必须包含出于某种原因不能输入的Unicode字符,则此选项非常有用。 如果使用此选项,则还必须将-u选项传递给genstrings,以便在结果字符串文件中正确解释十六进制数字。 如果指定了-u选项,那么genstrings会默认您的字符串为低位ASCII,并且仅解释反斜杠序列。

注意:如果您自己生成字符串文件(例如使用genstrings),请确保这些字符串文件在添加到项目中之前以UTF-8编码结尾。

4. Debugging Strings Files - 调试字符串文件

如果在测试过程中遇到问题,并发现检索字符串的函数和宏始终返回相同的key(与翻译的值相反),请在字符串文件上运行/ usr / bin / plutil工具。 字符串文件本质上是一种以特殊方式格式化的属性列表文件。 使用-lint选项运行plutil可以发现隐藏的字符或其他错误,以防止阻止字符串被正确检索。

后记

本篇主要讲述了字符串资源,感兴趣的给个赞或者关注,谢谢~~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容