IOS开发之国际化localization多语言支持

今天终于对国际化开始下手了,因为这个东西是ios很久之前就出来的,所以现在很多文章都是两年前的,查了几篇文章,最后成功走出国际范,现在把一些细节和重点,从头到尾捋一遍,如果你按照以前的文章设置没成功,祈祷这篇文章可以帮到你。

一、配置信息多语言设置

IOS的工程信息,比如软件名,软件版本,包括最新的ios10的权限声明,都是在Info.plist文件里面,所以如果你要国际化,这个文件里面的东西必不可少,比如软件名,中文:蚂蚁,英文:ant,再比如ios10对相册权限的声明。

这个文件的多语言配置是这样的

首先在Info.plist里面加上一条这个属性,并设置为true

Application has localized display name

1、创建InfoPlist.strings(文件名必须是这个)

屏幕快照 2016-12-16 下午4.15.10.png

2、设置localization

创建这个文件完毕之后,选择这个文件,点击右侧的localization,会默认创建两个Base和English,两个都打勾即可,我这里四个对应的是英文,中文,繁体中文,不要急后面会说怎么添加

屏幕快照 2016-12-16 下午4.44.25.png

3、查看工程里面Info.plist的key

屏幕快照 2016-12-16 下午4.50.01.png

通过代码模式就可以找到需要做多语言版本的key了,比如软件名,和使用蓝牙,相册的声明

<key>CFBundleDisplayName</key>
<string>东东blog</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>是否允许该APP使用蓝牙</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>是否允许访问相册以便保存截图?</string>
<key>UIApplicationShortcutItems</key>

那么这个CFBundleDisplayName就是你要找的key值,其他的也是一样的

4、设置对应key值的多语言

屏幕快照 2016-12-16 下午4.49.35.png

点开对应的文件版本,添加对应的key,你可以选择右键》open as》ASCII Property List这种方式打开,也可以直接在这个文件里面写源码,比如在infoPlist.strings(English)里面添加

{
    NSBluetoothPeripheralUsageDescription = "Do you allow the APP to use Bluetooth for more stable message push? (not required)";
    NSPhotoLibraryUsageDescription = "Are you allowed to access albums to save screenshots?";
    CFBundleDisplayName = "dongdong blog";
}

然后在infoPlist.string(Traditional)里面添加

{
    "NSPhotoLibraryUsageDescription" = "是否允許訪問相冊以便保存截圖?";
    "NSBluetoothPeripheralUsageDescription" = "是否允許該APP使用藍牙以便更穩定的接收消息推送?(非必選)";
    CFBundleDisplayName = "東東blog";
}

添加好之后,即可,就会根据你手机设置的语言来自动变显示的语言提示和软件名了。

注意,层级要正确,如果在Info.plist里面是在最外边可以这么写,但是如果是在一个字典中,那么也需要把字典加进去,保持层级不变,不能只写想修改的那个key值。比如快捷菜单的层级在Info.plist里面是这样,如果想修改「查看密码」这个文字

<key>UIApplicationShortcutItems</key>
    <array>
        <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypeLove</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>查看密码</string>
            <key>UIApplicationShortcutItemType</key>
            <string>all</string>
        </dict>
    </array>

那么你在多语言里面就要这么写

 "UIApplicationShortcutItems" = (
    {
        "UIApplicationShortcutItemType" = all;
        "UIApplicationShortcutItemTitle" = "View Password";
        "UIApplicationShortcutItemIconType" = "UIApplicationShortcutIconTypeLove";
    },
    );

或者使用ASCII Property List模式按照层级添加

5、base的作用

有人问Base是什么,其实Base相当于一个默认的选项,比如这里添加的语言有英文,简体中文,繁体中文,当手机设置为简体中文的时候,会默认读取简体中文的文件,但是如果手机设置为日文了,这里并没有没有添加日文的多语言,那么手机就会读取base里面的语言了,所以如果是面向全球,最好把Base里面的也设置为英文,因为用英文的国家远比简体中文的国家多啊。

二、软件内容里面多语言

软件里面肯定有很多需要多语言的地方,所以需要全部找出来并且实现多语言

1、创建Localizable.strings文件(名字必须是这个)并设置localization

这里和第一部分一样,创建strings文件,名字也是固定的,设置方法也是相同的

2、找出需要设置多语言的文字并设置key

创建好这个文件之后,找到想要设置多语言的文字,比如『胡东东,博客,哈哈』这三个词,然后在Localizable.strings(English)直接写即可,key是自己任意设置的,后面通过这个key读取

"AppCommon1" = "hudongdong";
"AppCommon2" = "blog";
"AppCommon3" = "haha";

在Localizable.strings(Simplified)添加

"AppCommon1" = "胡东东";
"AppCommon2" = "博客";
"AppCommon3" = "哈哈";

然后在需要用这些文字的地方使用

NSLocalizedString(@"AppCommon1", nil)
NSLocalizedString(@"AppCommon2", nil)
NSLocalizedString(@"AppCommon3", nil)

替代。

比如直接输出

NSLog("%@",NSLocalizedString(@"AppCommon1", nil));

这样即可实现内容的多语言化了,注意,如果你创建的文件不是Localizable.strings这个名字,那么这个NSLocalizedString是获取不到信息的,打印出来的是AppCommon1。

base的作用和上面说的那个是一样的,如果有对应的多语言文件,比如简体中文对应的Localizable.strings(Simplified),就读取这个文件里面的信息,如果没有这个文件,就会读取base里面的信息了。

三、添加多语言

默认的多语言是只提供一个base和一个English,那么怎么像我一样添加简体中文和繁体中文呢?

这是在project里面添加的

屏幕快照 2016-12-16 下午5.48.04.png

选择项目的PROJECT,然后里面会有Localizations选项,点击下面的加号即可添加对应的版本,系统会自动在InfoPlist.strings和Localizable.strings文件里面添加,默认创建的内容是复制的base里面的。

四、关于使用语言的顺序是这样的(2017-12-11续)

感谢@Winson的反馈,iOS对应用语言的判定遵循的原则是:

1、 查看应用是否针对系统语言做国际化,如有,选择对应的系统语言
2、 遍历系统对首选语言,如果存在对首选语言有做国际化,选择该首选语言,首选语言看手机语言设置里面的顺序

DamonScreenShot 2017-12-11 11.32.17.png

3、 全部没有对情况下使用Info.plist里面Localization native development region对应的本地化语言。

DamonScreenShot 2017-12-11 11.50.17.png

举个例子,比如一个工程对英文、繁体中文、简体中文做了国际化,那么就会有这几个文件,那么情况就是这样的:

DamonScreenShot 2017-12-11 16.02.28.png

  1. 如果你选择了英文,那么就会读取你在Localizable.strings(English)的国际化字符串,如果你选择了简体中文,就会读取Localizable.strings(Simplified)的国际化字符串。
  2. 如果你选择了英文之后,又选择了俄文,因为没有对俄文进行国际化,所以就会去读取你系统的首选语言,而这个语言的排行一般是你上次选择过什么,在列表就会靠前,这样的话就会去读取你英文Localizable.strings(English)的国家化字符串,而如果你上次是选择了简体中文,又选择了俄文,那就是读取你简体中文Localizable.strings(Simplified)的国际化字符串,如果在首选语言中第一个排行的是英文,第二个是中文,但是也没有英文的国际化文件存在的话,就会尝试去读你中文的国际化字符串,以此类推,。
  3. 如果你把首选语言全都删除了,只剩下一个现在使用的俄文,那么在没有俄文的国际化字符串,也没有其他首选语言的,那就会去读取你在info.plist里面设置的那个本地化语言,比如你设置的是China,那么就会去读Localizable.strings(Simplified)的国际化字符串,如果设置的是Taiwan,就是去读Localizable.strings(Traditional)的国际化字符串。
  4. 又比如在3的基础上,你在info.plist设置的是China,但是并没有Localizable.strings(Simplified)的国际化字符串文件,那么就会去读Localizable.strings(Base)的国际化字符串了。

有个特殊的问题我没有搞明白为什么,就是如果理论上info.plist设置的如果是United States或者United Kingdom的时候,如果使用俄文或者日文之类的,应该在没有的时候,去尝试读Localizable.strings(English),但是出乎我意料的是他们读的都是Localizable.strings(Base),直接跳过了,有知道原因的请说下

五、关于Base这个文件

这个文件相当于初始化文件,比如你在base里面写了

"AppCommon1" = "HuDong";
"AppCommon2" = "Hu";
"AppCommon3" = "HuBLOG";

那么在创建其他的国际化文件时,比如Localizable.strings(Simplified),会自动将这些内容复制到新文件里面,相当于内容直接初始化了,而如果是StoryBoard的文件或者xib的base文件则是可以将里面布局的所有字符串,比如UILabel的显示内容,全部可以提取出来到其他翻译文件里面,比如Main.strings(English),这样就不用你一个一个空间查找了。

六、总结

  1. InfoPlist.strings(Base)和Localizable.strings(Base)的作用是相同的,都是在没有对应本地化过的语言的时候,会采用Base这个文件里面的东西,所以做全球话的话最好Base里面设置成英文的,应用范围更广,如果你有更大的人力,可以把每个国家都本地化。
  2. 两个文件名字要注意,否则会出现读取不到的情况
  3. 文件里面key的双引号加不加无所谓,但是最好是加上
"NSPhotoLibraryUsageDescription" = "Are you allowed to access albums to save screenshots?";
CFBundleDisplayName = "hudongdong";

4、本地化之后,可以在itunesConnect后台给自己的软件单独添加本地化过的介绍和截图

七、参考文章

Last modification:December 11th, 2017 at 04:43 pm
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

2 comments

  1. Winson

    Base没起效果,读了上一次设置的语言,请问怎么解决

    1. 东东
      @Winson

      base是当其他的语言没有的时候才会去读取,比如你没有本地化西班牙语,那么如果手机是西班牙语的话,默认就会读取base里面设置的,但是如果你已经设置了西班牙语对应的本地化,那么会自动读取西班牙语里面的,而不是base里面的,你测试的时候要去切换手机对应的语言,没有了才是去base

Leave a Comment