美文网首页
Localization - 国际化

Localization - 国际化

作者: oncezou | 来源:发表于2020-02-28 15:51 被阅读0次

    国际化的实质是根据不同的语言加载对应的.lproj资源文件。.lproj中包含InfoPlist、Localizable、Main等资源文件。每新增一种语言,就会在工程目录下生成与之对应的.lproj资源文件夹。


    国际化的步骤
    1.新增语言
    add localization.png
    添加语言后,会在工程目录下生成xx.lproj文件夹(xx是语言的编码)。
    eg: 添加Chinese(Simplified)(zh-Hans) 对应生成 zh-Hans.lproj
    2.Main.storyboard国际化(主要针对带文本的控件)
    Main.storyboard.png
    • 1.Localization国际化: 选择Localize, 勾选多语言,会在对应xx.lproj的文件夹下新增Main.strings,并且Main.storyboard会变成文件夹的形式,可以查看所有语言的Main.strings
    • 2.使用:
    /*————配置UI控件的文本内容————*/ 
    // Main.strings(English) 
    "PBP-pq-8OJ.text" = "Localizable";
    // Main.strings(English) 
    "PBP-pq-8OJ.text" = "国际化";
    
    3.Info.plist国际化

    Info.plist主要是App信息和权限的配置。Info.plist国际化的常见使用在:App的名称、权限开启的提示等。
    eg: 1. 名称: 国内 抖音小视频 海外 TikTok
    2. 权限提示: 相机/相册权限开启的多语言提示等

    • 1.新建InfoPlist.strings文件(固定命名)


      InfoPlist.png
      1. Localization国际化(操作同Main.storyboard)
    • 3.定义:
    /*————配置App信息————*/ 
    // InfoPlist.strings(English) App在English语言系统下的名称
    "CFBundleDisplayName" = "Localizable";
    // InfoPlist.strings(Traditional) App在Traditional语言系统下的名称
    "CFBundleDisplayName" = "国际化";
    

    配置InfoPlist.strings,那么Info.plist会在不同的语言系统下,展示不同的内容。

    4.字符串的国际化
      1. 新建Localizable.strings文件(固定命名,操作同Info.plist国际化)
      1. Localization国际化(操作同Info.plist国际化)
      1. 使用:
    /*——————————定义文字内容——————————*/ 
    // Localizable.strings(English) 
    "Language" = "English";
    // Localizable.strings(Traditional) 
    "Language" = "繁体";
    // 使用
    let language = Bundle.main.localizedString(forKey: "Language", value: nil, table: nil)
    
    5.图片国际化
    image.png

    将图片添加到对应的语言环境下。

    注意:
    Assets.xcassets是不能国际化的,和Main、Info.plist、Localizable不同的是:图片不能新建.strings文件,并且图片国际化之后还是保存在Assets.xcassets中,并不会存储在对应语言的.lproj文件夹下。

    国际化的调试方法
    • 1、首先想到的当然是切换iPhone系统的语言系统,来调试国际化。这是最标准的方案,但是频繁的操作还是比较繁琐的。
    • 2、Xcode提供了切换语言的功能。
      Arguments.png
      在Arguments Passed On Launch添加-AppleLanguages (语言编码),然后选则需要的语言运行。
      缺点:InfoPlist.strings的国际化不会生效。

    国际化的实践
    1. Main.storyboard自动更新

    问题:在实践国际化中如果使用storyboard,会发现Main.strings不会同步storyboard,这是很糟糕的问题。

    解决方案:

      1. 手动同步
        如果还没有配置Main.strings具体的内容,可以先删除Main.strings,再新建。这样storyboard的控件会同步到Main.strings
        但是如果开发过程中修改storyboard(Main.strings有国际化的内容),就不能这样操作了。
        只能获取控件的ObjectID,手动编辑Main.strings。(获取控件的ObjectID办法:可以在对比storyboard的修改中查找ObjectID)
        手动同步无疑是低效的
      1. 自动同步
        自动同步是通过脚本的方式来实现。
      • 2.1 将AutoGenStrings.py脚本放置在${SRCROOT}/${TARGET_NAME}/RunScript/目录下,也就是项目根目录的RunScript的文件夹下,没有就新建文件夹。
      • 2.2 配置Run Script
        AutoGenStrings.png
        添加运行命令:
        python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}
    • 2.3 修改Deployment PostprocessingYes
      Deployment Postprocessing: 指定二进制文件是否接受部署后处理。

      Deployment Postprocessing.png

    Deployment Postprocessing最好是在需要的时候开启,不需要时关闭。

    AutoGenStrings的命名和路径并不是固定的,可以自定义。但是存放的路径和Run Script配置的必须是一致的,否则找到不到脚本。

    注明:AutoGenStrings是其他作者的作品,因为没有找到真正的出处,所有没有标注。

    2. 应用内切换语言环境

    App内切换语言,这是很常见的需求。
    前面说过: 国际化的实质是根据不同的语言设置加载对应的.lproj资源文件夹。所以切换语言就是切换.lproj

    大致的步骤:

    • 2.1 切换.lproj,并保存当前语言信息在本地。
    • 2.2 重置整个应用。
    @objc private func setLanguage() {
            
        let languages = Localize.availableLanguages()
        let index = Int.random(in: 1..<3)
        Localize.setCurrentLanguage(languages[index])
            
        let story = UIStoryboard(name: "Main", bundle: BundleEx.main)
        let viewCtrl = story.instantiateViewController(withIdentifier: "RootVC")
        DispatchQueue.main.async {
            if #available(iOS 13.0, *) {
                let windows = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
                guard windows != nil else {
                    return
                }
                windows?.rootViewController = viewCtrl    
            } else {
                UIApplication.shared.keyWindow?.rootViewController = viewCtrl
            }
        }
    }
    

    具体的实践可以查看Localizable示例

    问题:
    App内切换语言,按照上面 图片国际化 的操作,是无法切换图片的,因为国际化的图片不存储在.lproj中。所以要想同时切换图片,只能将 图片名称国际化 ,使用字符串国际化的方式。

    其他:
    因为示例中设置语言放在一级页面,所以直接重置rootViewController,如果放在层级比较深的页面,常见的做法是:用一个蒙层遮住整个屏幕,然后屏幕下重置rootViewController,并且按之前的push栈中的层级,一层层的push到设置语言的页面。可参考iPhone的设置语言或者微信的设置语言。

    3. Excel导出Localizable.strings

    如果App设置的语言版本,以及内容太多,手动去编写Localizable.strings无疑是很耗时的。
    TCZLocalizableTool是一个国际化工具,能帮助将Excel表转化为多版本的Localizable.strings,并且还提供多个关于国际化检测的功能。

    相关资源

    TCZLocalizableTool

    相关文章

      网友评论

          本文标题:Localization - 国际化

          本文链接:https://www.haomeiwen.com/subject/nkjkhhtx.html