iOS学习笔记-国际化

最近在给公司的项目做国际化,不得不说是一件很繁重的工作,因为公司项目使用的xib较多,所以既要考虑代码的国际化也要考虑xib的国际化,同时项目中还要求对权限请求提醒做国际化,种种种种。

网上相关国际化的博文有很多,不过并没有一个全面的针对代码、xib、storyboard以及项目配置整体的一个国际化的介绍,所以这里一口气就全部搬上来了。

代码的国际化

给项目添加国际化

给项目添加国际化

创建Localization.strings文件

打开 File>New>File,选择Resource中Strings Fils,新建一个Strings文件,并命名为Localizable.strings
新建Localizable.strings

新建完Localizable.strings后,接下来把所有需要国际化的字符全部写在这个strings文件中就OK了。
举个例子

1
2
3
4
5
6
7
8
if (![CLLocationManager locationServicesEnabled]) {
[[[UIAlertView alloc] initWithTitle:@"定位服务未打开"
message:@"定位服务当前可能尚未打开,请设置打开!或者手动设置"
delegate:self
cancelButtonTitle:@"好的"
otherButtonTitles:nil, nil] show];
return;
}

拿这段代码做实例,我们需要给提示的信息做国际化。可以使用这个方法:

1
[[NSBundle mainBundle] localizedStringForKey:@"key" value:@"" table:nil]

为简化操作,往往定义一个宏来做国际化

1
#define LOCAL_LANG(LangKey) [[NSBundle mainBundle] localizedStringForKey:(LangKey) value:@"" table:nil]

于是整块代码就可以写成这样

1
2
3
4
5
6
7
8
if (![CLLocationManager locationServicesEnabled]) {
[[[UIAlertView alloc]initWithTitle:LOCAL_LANG(@"Alert_Title_LocationNotSupported")
message:LOCAL_LANG(@"Alert_Content_LocationNotSupported")
delegate:self
cancelButtonTitle:LOCAL_LANG(@"BT_OK")
otherButtonTitles:nil, nil] show];
return;
}

当然,相应的Localization.strings文件中需要有对应的描述:

1
2
3
"Alert_Title_LocationNotSupported" = "GPS not supported";
"Alert_Content_LocationNotSupported" = "Please go to setting and turn on the GPS service";
"BT_OK" = "OK";

对Localization.strings文件做国际化

接下来我们就要对这个strings文件做国际化
选择Localization.strings文件,点击右侧localize文件,然后会弹出一个框,这个框代表要把当前文件作为哪种语言。一般选择Base
这里的列表可选语言根据你的项目设置中的语言来显示
![对Localization.strings文件做国际化][4]

生成多语言文件

输入国际化中文

好!大功告成,这个时候如果将系统语言切换成中文,就会给出中文的提示

xib和storyboard的国际化

苹果官方推荐的方法

在xib和storyboard右侧有localize选项,相应的处理方法和strings文件一样,选择国际化后会生成对应的strings文件,抽出xib中所用的字符,只需要针对每个xib做国际化就OK

个人推荐的方法

如果一个项目中有30个xib,项目需要有8种语言,那就意味着需要维护30*8=240个strings文件,然而很多情况下每个文件里只有少数几个字符,这样的维护成本太大了,很难保证不遗漏。
所以可以尝试在xib中用Localization.strings中的键作为值使用,然后对于需要国际化的view,统一调用如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+ (void)replaceTextWithLocalizedTextInSubviewsForView:(UIView*)targetView {
for (UIView* view in targetView.subviews) {
if (view.subviews.count > 0) {
[self replaceTextWithLocalizedTextInSubviewsForView:view];
}
if ([view isKindOfClass:[UILabel class]]) {
UILabel* label = (UILabel*)view;
label.text = LOCAL_LANG(label.text);
[label sizeToFit];
}
if ([view isKindOfClass:[UIButton class]]) {
UIButton* button = (UIButton*)view;
[button setTitle:LOCAL_LANG(button.titleLabel.text) forState:UIControlStateNormal];
}
if ([view isKindOfClass:[UITextField class]]) {
UITextField* textField = (UITextField*)view;
[textField setPlaceholder:LOCAL_LANG(textField.placeholder)];
}
}
}

简单的说就是在viewDidLoad的时候或者是awakeFromNib的时候对xib中的字符进行替换。

项目配置的国际化

这个的主要需求是App的名称需要做国际化,其实这很简单
首先,在项目的info.plist中加入
Application has localized display name的这个选项,并且选择YES

然后,新建一个strings文件,明名为:infoPlist.strings
对其进行Localize操作,在不同国家文件里写入不同的App名
“CFBundleDisplayName” = “Forecast”;
“CFBundleDisplayName” = “天气小助手”;

当然,还有一些项目配置中需要国际化的,比如说
“NSContactsUsageDescription” = “允许使用您通讯录中的联系人添加好友。并且您的通讯录会受到加密保护,不会用作其他任何用途”;
在iOS8中可以在配置文件中配置权限请求的提示文字等等