iOS 语言本地化/国际化

语言本地化,又叫做语言国际化,是指根据用户操作系统的语言设置,自动将应用程序的语言设置为和用户操作系统语言一致的语言,这就要求应用程序所展示的文字、图片等信息,能够让使用不同语言的用户读懂、看懂,进而需要为同一个应用程序适配多种语言,我们日常使用的微信、支付宝等 App,都做了比较好的本地化,App 会根据系统的语言匹配合适的 App 内部语言,也可以直接在 App 内部切换成自己需要的语言,趁着自己项目里需要做本地化,本文就说说 iOS APP 如何本地化

配置需要本地化的准备

首先在工程里使用 Command + N,选择 iOS -> Resource -> Strings File,新建一个 Strings 文件,文件名最好命名为 Localizable

创建成功之后在工程里多了一个名为 Localizable.strings 的文件

接着选中 Localizable.strings 在 Xcode 右边 File inspector 中点击 Localize...,在弹框中选择 English 点击 Localize

然后选中 project -> Info -> Localizations,然后点击 +,添加需要本地化的语言,如下图

本文以中文简体、中文繁体、韩语以及英文作为本地化的语言

添加完需要本地化的语言之后,可以看到 Localizable.strings 下面自动生成四个语言的文件

这里 Base 并没有勾选,其实我们新建一个工程项目,在项目目录里都可以看到有一个 Base.lproj 文件夹,实际上我们项目创建默认使用的是 Base 的本地化。这也是为什么每次创建项目Main.storyboard 会在Base.lproj 的文件夹中的原因,系统默认创建的一个英文本地化配置(里面有两个文件正好跟Base.lproj 中的对应,目前可以理解 Base 也是英文的一种本地化,实际上如果我们勾选了 Base ,再取消 Xcode 会建议我们把 Base 文件移动到英语本地化文件中),我们要做多语言的本地化,所以全部使用我们自己文件化文件,所以这里不勾选 Base

接下来再新建一个 InfoPlist.strings 文件,方法和上面 Localizable.strings 一样,同样的右边勾选需要本地化的语言

本地化

上面的准备工作准备好之后就可以开始对项目进行本地化操作了

应用名称本地化

应用名本地化是指同一个 APP 在不同的语言的设备上显示不同的名称,例如:微信在中文环境中 APP 名称为 微信,在英语环境中名称为 WeChat,支付宝在中文环境 App 名称为 支付宝,在英语环境中名称为 AliPay

比如我的应用名称希望在中文环境名称为:国际化,英文环境名称为:Localization,在香港地区名称为:國際化,应用名本地化要用到 InfoPlist.strings 文件,我们只需要在对应的语言文件中添对应的名字

简体环境,在 InfoPlist.strings(Chinese(Simplified)) 添加

1
CFBundleDisplayName = "国际化";

英文环境,在 InfoPlist.strings(Chinese(Traditional)) 添加

1
CFBundleDisplayName = "Localization";

繁体环境,在 InfoPlist.strings(english) 添加

1
CFBundleDisplayName = "國際化";

韩文环境,在 InfoPlist.strings(Korea) 添加

1
CFBundleDisplayName = "국제화";

CFBundleDisplayName可以使用双引号,也可以不使用双引号!

这样就完成了 APP 名称的本地化,当你在设置里面切换到不同的语言之后,App名称就会显示为相对应语言的 APP 名了,实际上 InfoPlist.strings 还可以完成 Info.plist 文件里面的全部本地化,比如当 APP 要访问系统相册的时候,请求用户允许的时候,相关提示语也可以根据不同的语言环境进行不同的语言提示,有兴趣的可以自行尝试,本文就不做讲解了

代码中字符串的本地化

字符串本地化,就是指 App 内的字符串在不同的语言环境下显示不同的内容,比如:标题文字、按钮文字、提示框文字等

字符本地化和 App 名称本地化过程是一样的原理,只不过使用的文件不同,字符串本地化需要使用 Localizable.strings ,具体做法和在 InfoPlist.strings 本地化应用名是一样的

我们需要在 Localizable.strings 下对应的文件中,分别以 Key = Value 的形式,为代码中每一个需要本地化的字符串赋值,比如

Localizable.strings(Chinese(Simplified)) 添加

1
"点一下,不会怀孕" = "点一下,不会怀孕";

Localizable.strings(Chinese(Traditional)) 添加

1
"点一下,不会怀孕" = "點一下,不會懷孕";

Localizable.strings(english) 添加

1
"点一下,不会怀孕" = "Click it, no pregnant";

Localizable.strings(Korea) 添加

1
"点一下,不会怀孕" = "임신하지, 클릭";

在添加完上面的本地化字符串之后,回到代码中,在需要设置字符串的地方使用 NSLocalizedString(key: String, comment: String) 读取本地化字符串

1
2
3
4
5
6
7
// key是Localizable.strings文件中等号左边的字符串,comment是注释,可以传空字符串
// 如果没有对字符串进行本地化或者找不到key对应的值,NSLocalizedString将直接返回key这个字符串
NSLocalizedString(key, comment)
// 如果你的字符串资源文件名不是 Localizable.strings,如qt.strings,那么你就得使用 NSLocalizedString(key, tableName, bundle, value, comment) 来读取本地化字符串,tableName 替换为 qt
// 使用不同名字的字符串本地化文件可以把本地化字符串分开、便于管理,也可以在多人合作开发各自管理自己的本地化资源文件
NSLocalizedString(key, tableName, bundle, value, comment)

代码中使用本地化字符串:

1
clickBtn.setTitle(NSLocalizedString("点一下,不会怀孕", comment: ""), for: .normal)

效果如图

图片本地化

本地化图片,有两种方式,第一种方式和本地化代码中的字符串一样,通过 NSLocalizedString(key,comment) 来获取相应的字符串,然后根据这个字符串再获取图片,这就需要每种语言环境下用不同名称命名一套图片

第一种方法

1
2
3
let imageView = UIImageView()
imageView.image = UIImage(named: NSLocalizedString("icon", comment: ""));

第二种方法

把一张图片拖入工程,比如 icon.png,选中图片,右边File inspector 中点击 Localize...,接着在弹框中选择 English 点击 Localize,再把 icon.pngFile inspector 的语言本地化全部勾选上

选择 icon.png 然后 Show in Finder,会发现 en.lprojko.lprojzh-Hans.lprojzh-Hant.lproj 四个本地化资源文件夹里面各有一张 icon.png 的图片

然后根据我们需要把不同语言环境下的图片名称都改为 icon.png,放入各自对应的本地化资源文件夹中,替换掉之前的 icon.png,本地化代码和第一种方式是一样的

1
2
3
4
5
6
7
8
9
let imageView = UIImageView()
imageView.bounds = CGRect(x: 0, y: 0, width: 200, height: 200)
imageView.center = view.center
imageView.image = UIImage(named: NSLocalizedString("icon", comment: ""));
view.addSubview(imageView)

效果如图

我觉得第一种方式要更简单,我们只需要新建一个 strings 文件专门用来本地化图片字符串,这样也可以方便管理

XIB(Storyboard)本地化

使用 Xib 自定义一个 View,往里面拖一个 UILabel ,选中 Xib 文件,点击右边 File inspector 中的 Localize...,然后把对应的语言本地化全部勾选包括 Base

这时可以发现,CustomView.strings 文件里面自动添加了类似如下的内容

1
2
/* Class = "UILabel"; text = "自定义视图"; ObjectID = "J7V-O2-VkG"; */
"J7V-O2-VkG.text" = "自定义视图";

然后和之前一样,在对应的语言本地化文件中修改我们要显示的本地化文字,修改好之后效果如下

以后在 Xib 文件的中添加 UI 控件时,这里的文件并不会自动更新,
我们就要自己找到新添加控件的 Object Id, 就是上面类似 J7V-O2-VkG 这样的东西,在 Xib 选中相应的控件,然后右边Identity inspector 里面找 Object Id,然后手动添加上述类似的代码

如果不想通过代码改 Xib 的本地化,选中 Xib ,在右边语言本地化的右边,选择 Interface Builder Cocoa Touch XIB,此时选择的 CustomView.strings 就变成了 CustomView.xib,这样相当于为每一种本地化语言生成了一个对应的 Xib

不过,最好是把 Xib 中的页面全部布局好了,再去做本地化,后续添加控件再去更新,Storyboard 的本地化和 Xib 是类似的就不再赘述

其他国际化

项目里可能还有音频文件、视频文件等资源文件需要国际化,这些文件一般是通过文件目录访问的,完全可以用不同名字去区分,根据语言环境对应的加载这些资源文件

以上就是开发中 iOS 开发中本地化的基本过程

2016/06/11 补充

补充一下本地化的测试相关内容,本地化要看效果每次都去设置里切换语言是在太累

在 Xcode 中,可以使用预览功能,在不运行应用的情况下,检测国际化和本地化的结果,选择一个 .storyboard.xib 文件,打开辅助编辑器,在左边的弹出菜单中选择 Preview,通过右下角语言选项,选择不同的本地化语言查看预览效果

预览过后,可以通过设置应用启动时的参数,在设备上测试国际化和本地化的结果,而不需要修改设备的设置。编辑 Scheme,选择 Run -> Options,在 Application Language 一项中,可以选择对应语言资源,这样就不用测试不同的语言都去设置里面修改了

另外如果你的项目使用 Auto layout,可以选择 Double-Length Pseudolocalizations,它会重复重复本地化字符串,更改视图的大小和位置

还可以用选择 Right to Left Pseudolocalizations,测试从右往左书写的语言如阿拉伯语言的效果

勾选 Show non-localized strings 项,可以检测未本地化的文本,其会以大写形式显示

相关文章阅读:

iOS 国际化与本地化

About Internationalization and Localization

Testing Your Internationalized App

本人刚开始写博客,主要是为了给自己的知识点做一个笔记,方便自己以后查阅,如果能让别人有所启发也是荣幸之至!如有错误,欢迎指正!