iOS学习(六十五)添加国际化 / 本地化以及多语言问题(文档方向)

对app添加多语言十分简单,按照以下步骤即可:

Part 1. 代码中的国际化

第一步: 创建Strings File文件(Resource -> Strings File)

创建国际化文件

文件名称必须为Localizable.strings

注意文件名称

第二步: 点击国际化按钮

点击按钮

出现国际化选项即可:


国际化类型

第三步: 添加语言 (工程文件 -> Project -> 添加)

国际化是针对于项目而非Target

添加新语言

选择需要添加的语言:

选择语言.png

选择需要国际化的内容:

选择内容

注意: 如果是先执行第三步,那么这里没有第三个选项。

点击Finish后,可以看到localizable文件多了一个下拉文件

localizable

第四步: 添加国际化Key-Value

Key-Value

在代码中使用NSLocalizedString(@"Key1", @"这是一个说明")即可让该字符串替换为国际化字符串

Part 2. 项目配置中的国际化

项目配置和代码国际化十分相似,创建Strings File文件,必须命名为InfoPlist。选中文件,点击右侧Localize ...按钮开启国际化即可。此步骤参考Part 1 中的配置方式即可。

这里特殊的地方是,需要国际化的是特殊的Key,这些Key 的查看方式如下:

使用source code 方式打开info.plist文件

这里<key>标签中的即是对应的Key:

<key>标签

Part 3. 多语言问题(接口国际化)

当和服务器进行交互的时候,需要将对应的语言传给服务器,此时,由于各端的差异(iOS、Android、Web )通过系统方法获取到同一种的语言字符串是略有差异的,此时,就需要对其进行约定,统一处理。

一、 获取系统语言

通常,我们通过以下代码获取当前系统语言:

    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    NSArray* languages = [defs objectForKey:@"AppleLanguages"];
    NSString* preferredLang = languages.firstObject;

或者

NSString *preferredLanguage = [[[NSBundle mainBundle] preferredLocalizations] firstObject];

preferredLang 即当前的系统语言。

二、 获取语言误区(语言不仅仅是语言,包含语言+地区)

通过代码获取语言时,往往看到这样的:en-GBen_GB, 那这两个的区别是什么?

1. 首先要明确Language IDLocale ID的关系

官方文档,一开始就给出了两者的定义

Language IDs identify a language, dialect, or script and are used to name language-specific resource folders stored in the app bundle.
翻译:
Language IDs 标识一种语言、方言 或者(一种语言的)字母系统 并 用于 存储 在应用程序包中 有特定语言命名的 资源文件夹中。

Locale IDs identify a set of regional conventions and are used in APIs—such as the NSLocale, NSDateFormatter, NSNumberFormatter, and NSCalendar classes—where region information is needed to format data.
翻译:
Locale IDs 标识一组约定区域 并 用于需要 区域信息 格式化日期的 API(例如 NSLocale、NSDateFormatter、NSNumberFormatter 和 NSCalendar 类)中

OS X and iOS use standard language ID and locale ID formats that consist of language and region designators. For example, using a language combined with a region designator, a language ID can distinguish between different languages and regional dialects.
翻译(机翻):
OS X 和 iOS 使用由语言和区域指示符组成的标准语言 ID 和区域设置 ID 格式。 例如,使用语言与地区指示符组合,语言 ID 可以区分不同的语言和地区方言。

由此可见,bundle中的那些xxx.lproj文件的名称xxx, 就是Language ID。其实这里说的不全,这里只是表明了应用程序包中,语言资源文件名称(这里表述的不全,下文详述)。
2. Language ID 详述

文档中有对Language ID更全面的解释:

A language ID identifies a language used in many regions, a dialect used in a specific region, or a script used in multiple regions.
To specify a language used in many regions, use a language designator by itself.
To specify a specific dialect, use a hyphen to combine a language designator with a region designator.
To specify a script, combine a language designator with a script designator.
For example, to specify common English, use the en language designator as the language ID. To specify the English language as it is used in the United Kingdom, use en-GB as the language ID.

中间三句,表明了language ID的表述方式:

1. To specify a language used in many regions, use a language designator by itself.

要指定在许多地区使用的语言,请单独使用语言指示符。
比如, 直接使用en

2. To specify a specific dialect, use a hyphen to combine a language designator with a region designator.

要指定特定方言,请使用连字符将语言指示符与地区指示符组合起来。
比如, 使用en-AU,表示English as used in Australia(澳洲英语)

tips: hyphen 的意思是连接符,即英文的中划线。

3. To specify a specific dialect, use a hyphen to combine a language designator with a region designator.

机翻:
要指定脚本,请将语言指示符与脚本指示符结合起来。
比如,使用zh-Hans,表示Chinese in the simplified script (简体中文)

结论:

language ID 是由语言 或者 语言-方言/script 或者 语言-地区 或者 语言-方言/script-地区 这样的结构组成,中间使用连接符(英文中划线)进行连接。

eg:语言选简体中文,地区选英国,获取到的语言就是zh-Hans-GB

eg:语言选英语(英国),地区选美国,获取到的语言就是en-GB。注意,这里是语言-方言/script的结构。
因为打印[NSLocale currentLocale]可以看到结果是en_US,这里可以看出地区是US。

eg:语言选英语,地区选中国,获取到的语言就是en-CN

3. Locale ID 详述

A locale ID identifies a specific region and its cultural conventions—such as the formatting of dates, times, and numbers.
To specify a locale, use an underscore character to combine a language ID with a region designator, as shown in Table B-5.
For example, the locale ID for English-language speakers in the United Kingdom is en_GB, while the locale for English-speaking residents of the United States is en_US.

中间的一句,表明了Locale ID的表述方式:
使用英文下划线_连接语言和地区。

结论:

locale ID是由语言_地区,这样的结构组成,中间使用英文下划线进行连接。

eg :语言选英语(英国),地区选美国,获取到的地区是en_US

3. 总结

看了文档以后,感觉描述的仍然有些模棱两可。不过,可以明确的是language IDlocale ID 并不是独立的,是互相包含的一种关系。

故,可以通过调用不同的API获取不同的值,再根据各自的特点进行解析。

比如:
[NSLocale currentLocale]获取到的就是local相关:

[NSLocale currentLocale]

[[NSBundle mainBundle] preferredLocalizations]获取到的就是language ID 相关:

[[NSBundle mainBundle] preferredLocalizations]

三、统一语言类型

通过以上几点,获取语言并处理采用如下方式即可:

    NSString *preferredLanguage = [[[NSBundle mainBundle] preferredLocalizations] firstObject];
    preferredLanguage = preferredLanguage.lowercaseString;
    
    // 特殊处理中文 简体繁体
    if ([preferredLanguage hasPrefix:@"zh-hans"]) {
        // 简体
        preferredLanguage = @"cn";
    } else if ([preferredLanguage hasPrefix:@"zh-hant"]) {
        // 繁体
        preferredLanguage = @"tw";
    } else {
        // 其他语言
        preferredLanguage = [preferredLanguage componentsSeparatedByString:@"-"].firstObject;
    }
    
    if ([preferredLanguage isEqualToString:@"en"]) {
        preferredLanguage = @"后台英语字符串";
    } else if ([preferredLanguage isEqualToString:@"fr"]) {
        preferredLanguage = @"后台法语字符串";
    }
    ...

Part 4. 如何发现的文档

在看[NSLocale availableLocaleIdentifiers]方法描述的文档中,我们找到了上述官方文档的地址:

Language and Locale IDs

一般说来,都是先看Xcode自带的文档说明,往往在其中就会帖一些网页文档的地址,网页版的文档往往更全面。

参考文档:

  1. About Internationalization and Localization(多语言官方文档)

  2. 3分钟实现iOS语言本地化/国际化(图文详解)

  3. iOS国际化实践(包含资源文件国际化)

  4. iOS本地化与国际化最佳实践。该文章中使用了Xcode导出/导入国际化文件以及storyboard国际化预览的步骤。可作为参考。

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

推荐阅读更多精彩内容