版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.05.09 |
前言
很多APP都有国际化版本,常见于一些大公司的产品,比如Facebook、Wechat等,那么国际化需要我们APP做哪些更改呢,接下来这几篇就一起来看一下APP的国际化和本地化。感兴趣的可以看上面几篇。
1. App的国际化和本地化(一) —— 简单介绍(一)
2. App的国际化和本地化(二) —— 查看语言和区域设置(一)
3. App的国际化和本地化(三) —— 国际化用户界面(一)
回顾
上一篇主要介绍国际化用户界面,本篇主要介绍国际化代码。
Internationalizing Your Code - 国际化代码
除了国际化您的用户界面之外,编写处理多种语言文本的代码。 首先将国际文本存储在字符串文件中,类似于Internationalizing the User Interface中base internationalization
使用的字符串文件。 还可以使用语言和区域设置敏感的API来枚举,搜索和排序代码中的文本。 使用标准文本视图来显示和解析文本输入。 让这些API为您处理不同编写和输入系统的复杂性。
Separating User-Facing Text from Your Code - 从代码中分离出面向用户的文本
应用程序所提供的所有面向用户的文本都需要进行本地化 - 也就是说,不包含在.storyboard
或.xib
文件中的面向用户的文本(如错误消息)需要在呈现之前被翻译成当前语言给用户。 iOS和OS X提供了一种在运行时从字符串文件中检索本地化文本的机制。 在您的代码中,将包含面向用户的文本的字符串替换为NSLocalizedString
宏的返回值。 当您导出本地化版本时,Xcode将搜索您的代码以查找宏,并在导出的本地化文件中包含字符串文件以进行翻译。 当您导入本地化时,Xcode会将代码使用的字符串文件添加到您的Xcode项目中。
例如,代替在代码中使用@“26.22 miles”
字符串,请使用:
NSLocalizedString(@"RunningDistance", @"distance for a marathon")
其中,@“RunningDistance”
是从本地化字符串文件中检索的文本的key。 @“distance for a marathon”
参数是一个关于存储在字符串文件中的键值对的注释,作为本地化器的一个提示。 如果您需要不同的行为,请使用Foundation Functions Reference
中介绍的采用更多参数的其他NSLocalizedString
宏之一。
提示:请勿覆盖key或从多个key组成短语。 一些语言具有性别文章,形容词结尾和完全不同的词序。 相反,将单独的键值对添加到字符串文件中所有唯一的短语。
例如,替换这些键值对:
/* Go to next page/chapter */
"GoToNext" = "Go to next %@";
"chapter" = "chapter";
"page" = "page";
每个短语具有不同的键值对:
/* Go to next chapter */
"GoToNextChapter" = "Go to next chapter";
/* Go to next page */
"GoToNextPage" = "Go to next page";
不要将数字放在可本地化的字符串中,因为不同地区可以使用不同的数字。
您不需要将所有键值对存储在相同的字符串文件中。您可以使用其他NSLocalizedString
宏来创建单独的字符串文件,也可以将它们存储在不同的包中。有关NSLocalizedString
宏的更多信息,请阅读 Resource Programming Guide中的String Resources。
要从字符串文件中检索本地化字符串,不是将其添加到字符串文件,请在NSBundle类中使用localizedStringForKey:value:table:方法。当对应于指定表的字符串文件不在您的项目中时,NSLocalizedString
宏和localizedStringForKey:value:table:方法返回值参数作为本地化字符串。
稍后,在导入本地化时,如Importing Localizations中所述,本地化的字符串文件将添加到您的项目中。 (或者,您可以直接从NSLocalizedString
宏中生成开发语言字符串文件,如Creating Strings Files for User-Facing Text in Your Code中所述。)
如果您的字符串包含复数名词或度量单位,请阅读Handling Noun Plurals and Units of Measurement以了解如何为具有不同复数规则的语言扩展此机制。
Using Unicode Strings - 使用Unicode字符串
对于所有面向用户的文本,请使用支持Unicode
的字符串对象 - NSString
,NSAttributedString
及其子类的实例。 Unicode
是编码世界所有书写系统字符的标准。 字符串对象封装以UTF-16格式编码的Unicode字符串。 用户看到的字符可以表示为Unicode字符串中的多个字符并进行编码。 因此,请使用处理组合字符序列的字符串方法,而不是字符串中的单个字符。 使用适当的字符串API进行迭代,搜索和排序。 使用正确显示Unicode字符串对象的标准视图和控件。
有关字符串对象的全面文档,请阅读String Programming Guide。
1. Accessing Characters in Strings - 获取字符串中的字符
NSString类通过允许您访问字符集群或ranges来处理字符编码的复杂性。 使用rangeOfComposedCharacterSequenceAtIndex:和rangeOfComposedCharacterSequencesForRange:方法确保您不会拆分字符串中的用户字符并打算文本。 这些方法在表示用户字符的字符串内返回一个range。
例如,表3-1显示了UTF-16和UTF-32编码中用户字符的数字表示形式。 请注意,无论使用何种编码格式,用户字符的长度都不相同。
视频:WWDC 2013 Making Your App World-Ready: International Text > Composed Character Sequences
2. Enumerating Strings - 枚举字符串
通过组合字符序列,单词,句子或段落来枚举字符串,而不是字符串中的单个字符。 要通过组合字符序列来枚举字符串,请使用enumerateSubstringsInRange:options:usingBlock:方法并传递NSStringEnumerationByComposedCharacterSequences作为选项参数。 要逐个枚举字符串(跳过标点符号),请传递NSStringEnumerationByWords作为options参数。
例如,如果将NSStringEnumerationByComposedCharacterSequences传递给enumerateSubstringsInRange:options:usingBlock:方法,它将返回用户字符,如同组合字符序列中一样:
如果字符串是:
你传递NSStringEnumerationByWords作为options参数,返回下面的词语:
注意空格和标点符号不包含在单词中。
视频:WWDC 2013 Making Your App World-Ready: International Text > String APIs: Iteration
3. Searching Strings - 搜索字符串
要使用区域设置敏感的比较算法搜索字符串的内容或验证字符串中是否存在字符串,请使用rangeOfString:options:range:locale:,将当前位置作为区域设置参数传递。 您可以组合并传递的常量作为选项参数:
-
- 不区分大小写的搜索。 例如,'B'与'b'相同。
-
- 忽略变音符号。 例如,'ö'等于'o'。
-
- 向后搜索。 (默认是向前。)
-
- 在起点搜索。
例如,如果要在字符串中搜索用户文本,请将NSCaseInsensitiveSearch
和NSDiacriticInsensitiveSearch
常量作为options
参数传递给rangeOfString:options:range:locale:方法。 通常情况下,搜索文本是一种大小写和变音不敏感操作,但排序文本是大小写和变音符号敏感。
4. Sorting Strings - 排序字符串
对于向用户显示的文本,请使用区域敏感的API进行排序和比较字符串。 不同的语言和地区有不同的排序顺序标准。 例如,法语中的变音符号很重要,而英语中则不是。 在某些语言中,多个字母被组合并影响排序顺序。
要使用区域敏感的比较算法,请使用与Finder产生相同结果的localizedStandardCompare:方法。
如果您不想获得与Finder相同的结果,请使用compare:options:range:locale:方法,将当前地区作为本地参数或localizedCompare:方法传递。
不要使用localizedCaseInsensitiveCompare:方法进行排序。
视频:WWDC 2013 Making Your App World-Ready: International Text > String APIs: Sorting
5. Displaying Text - 展示文本
使用标准视图和控件来处理Unicode文本布局和显示的复杂性。字符串中的字符不直接对应于屏幕上呈现的文本。屏幕上显示的是一系列字形。字形是字体中最小的可显示单位。字形可能代表一个字符,多个字符或字符的一部分。字符到字形的映射并不简单 - 它可以是多对多的。另外,一行中字形的顺序和位置很复杂。标准视图和控件甚至可以为您正确地设计双向文本 - 例如,包含英文单词和希伯来单词的字符串中的字符顺序与用于在视图中放置文本的顺序不同处理双向文本,如Handling Bidirectional Text中所示。
如果您需要编写自定义显示代码,请使用适当的低版本文本API。要了解iOS的文本类,请阅读Text Programming Guide for iOS和Mac,阅读Text Layout Programming Guide。
6. Parsing Text Input - 解析输入文本
用户可以用任何语言和格式输入文本。 iOS和OS X可识别用户正在键入的语言并提供适当的键盘选项。 如果您在用户输入时解析文本,请记住,键盘字符到语言字符之间存在多对多映射。
Parsing Language Characters - 解析语言字符
对于某些语言,用户一次不会输入一个字符。 也就是说,用户在键盘上按下的键不一定对应于该语言中的字符。 在法语中,用户通过从弹出式菜单中选择插入点来添加重音。 在日语和汉语中,用户输入语音表示并从候选列表中选择一个候选以确认标记的文本。 在这两种情况下,首先插入初步文本,然后在用户确认后将其转换为最终文本。
视频:WWDC 2013 Making Your App World-Ready: International Text > Text Input
Determining When the User Confirms Marked Text (iOS Only) - 确定用户确认标记文本的时间(仅限iOS)
要确定用户是否确认了标记的文本,请将markedTextRange发送到文本视图。 如果此方法返回空字符串,则用户确认了一些输入的文本。
Determining the Typed Language (iOS Only) - 确定键入的语言(仅限iOS)
要获取用户当前键入的语言,请使用UIResponder
类中的textInputMode属性,如下所示:
NSString * languageID = [[[UIApplication sharedApplication] textInputMode] primaryLanguage];
返回的字符串是语言ID,如Language and Locale IDs中所述,用于标识书面语言或方言。
要获取用户启用的一组语言,请执行以下操作:
NSArray * languages = [[[UIApplication sharedApplication] textInputMode] activeInputModes];
返回的数组包含UITextInputMode类的实例。
Detecting Personal Names, Mailing Addresses, and Phone Numbers - 检测个人姓名,邮寄地址和电话号码
在全球范围内,个人姓名,邮寄地址和电话号码的格式差别很大。 个人名称有很多不同的格式,包括组件的不同排序。 例如,在亚洲国家,姓氏后面跟着名字,两者之间没有空格。 邮寄地址的格式取决于国家。 电话号码在它们之间有不同的数字和标点符号。 要在文本视图中处理不同的输入格式,请使用Interface Builder
将数据检测器添加到文本视图。 数据检测器以许多不同的国际格式识别地址和电话号码,并可选择将其转换为链接。
要以编程方式在字符串中检测此类数据,请阅读NSDataDetector Class Reference。
Getting the Current Language - 获取当前语言
要从应用程序包获取应用程序使用的语言,请使用NSBundle
类中的preferredLocalizations方法
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
后记
本篇主要讲述了国际化代码,感兴趣的给个赞或者关注~~~