国际化

作者: 小朴同学 | 来源:发表于2019-02-17 17:34 被阅读1次

    demo

    1. storyboard中的文字
    2. 代码中的文字
    3. app名称的展示
    4. 资源文件的国际化
    5. 国际化脚本

    国际化原理

    核心思想就是为每种语言单独定义一份资源。
    iOS就是通过xxx.lproj目录来定义每个语言的资源,这里的资源可以是图片,文本,Storyboard,Xib等。
    每种语言都有自己的 语言代码.lproj文件夹,加载资源时只需要加载相应语言文件夹下的资源就OK
    例如:根目录下英语的为en.lproj,中文的为zh-Hans.lproj。

    国际化过程

    1. 首先添加国际化配置
      • 选中project->Info->Localizations,然后点击"+",添加需要国际化/本地化的语言,如下图(默认需要勾选Use Base Internationalization)
        图片引用于:VV木公子 image
      • 点击+后,选择后缀为Chinese (Simplified)(zh-Hans)简体中文,后缀为(zh-Hant)为繁体中文。
      • 在这说一句后缀问题,所有iOS支持的语言及后缀,都可以在点击+后出现的语言中找到,其中最下面的other下是全部的集合。其中英语的后缀为(en)
    2. 应用名称
      • 选中Info.plist(或者其他你想创建的位置,现在创建在info.plist所在的文件),按下键盘上的command + N,选择Strings File(iOS->Resource->Strings File)

      • 文件名字命名为InfoPlist,且必须是这个名字

      • 选中InfoPlist.strings,在Xcode右侧选中文件标志->选中Localize,目的是选择我们需要本地化的语言 如下图:

        image
      • 点击Localize后,在弹出框中->点击base->展开的列表中选择English->随后选中右下角的Localize

      • 此时右侧会变成下图模样,勾选Chinese

        image
      • 此时InfoPlist.strings变成了文件夹,文件中有两个文件。程序启动时,会根据操作系统设置的语言,自动加载InfoPlist.strings文件下对应的语言文件,然后显示应用程序的名字。

        • 在InfoPlist.strings(english)文件中加入如下代码:
        // Localizable App Name是App在英语环境环境下显示的名称
        CFBundleDisplayName = "Localizable App Name";
        或者
        "CFBundleDisplayName" = "Localizable App Name";
        
        • 在InfoPlist.strings(Chinese(Simplified))中加入如下代码
        CFBundleDisplayName = "国际化App名称";
        
      • app展示名字本地化结束
        补充

        InfoPlist.strings文件是对Info.plist这个配置文件进行的国际化,这个文件的国际化,不单单是app名称的设置,还包括权限的申请等的配置。关键在于这个文件的配置KEY是固定值,例如: app名字的key CFBundleDisplayName, 相机权限的申请key NSCameraUsageDescription等

        • 首先你将需要配置的属性添加到Info.plist文件中
        • 其次查看这个属性的key, 点击这个文件的任意一项,两个指头同时点击,选择弹出框的Show Raw Keys/Values,文件的展示就变成了key-value格式,此时你就可以找到你想要国际化属性的key
        • 最后在InfoPlist.strings文件中,做对应的配置即可
        • 详细操作参考 iOS10权限声明国际化
    3. 代码中字符串的本地化
      • 与上类似,创建一个Localizable.strings的文件,创建步骤与上面一致。
      • 然后我们只需要在Localizable.strings下对应的文件中,分别以Key-Value的形式,为代码中每一个需要本地化的字符串赋值
      // Localizable.strings (Simplified)文件中
      localization = "本地化";
      internationalizartion = "国际化";
      //Localizable.strings (English)文件中
      localization = "localization";
      internationalizartion = "internationalizartion";
      
      在要使用这些字段的.m文件中
      // NSLocalizedString(key, comment) 本质
      // NSlocalizeString 第一个参数是内容,根据第一个参数去对应语言的文件中取对应的字符串,第二个参数将会转化为字符串文件里的注释,可以传nil,也可以传空字符串@""。
      //#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
      NSString *localization = NSLocalizedString(@"localization", nil);
      NSString *internationalizartion = NSLocalizedString(@"internationalizartion", nil);
      self.array = @[localization, internationalizartion];
      取得并使用
      
      • 代码中字符串的本地化结束
      • 我们不需要在Localizable.strings(English)文件添加Key-Value。原因如下:系统根据某个key去获取对应的字符串时,如果没有找到,那么就会以key作为value返回。
      • 模拟不同的语言环境,不需要在模拟器中的设置中去做。在Xcode中,command+shift+<出现的界面中做如下设置:
        Run -> Arguments -> Arguments Passed On launch 中添加-AppleLanguages (en)和-AppleLanguages (zh-Hans)然后选中其中一个,运行的app中的语言设置就是相应语言的
        image
    4. 多人开发情况下的字符串本地化
      • 上面介绍的代码中字符串的本地化是使用的是默认的文件名"Localizable",因为启动程序时,系统将根据语言加载相应的文件得到其对应的字符串文件,这个字符串可以通过系统将NSLocalizedString中的宏生成名为“Localizable.strings”的文件。那么如何让系统加载我们自己命名的本地化文件而非系统默认的Localizable.strings呢?这就是 NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)的用处。
        也就是说,如果你的strings文件名字不是Localizable而是自定义的话,如VVS.strings,那么你就得使用NSLocalizedStringFromTable这个宏来读取本地化字符串。
      // key:系统根据key取字符串
      // tbl:自定义strings文件的名字
      // comment:可以不传
      NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
      
      .m文件中
      NSString *title = NSLocalizedStringFromTable(@"click", @"VVS", nil);
      [self.btn setTitle:title forState:UIControlStateNormal];
      
    5. 图片本地化
      • Assets.xcassets 不支持本地化,所以需要本地化的,可以单独放到一个新的文件目录下
      • 拖拽一张需要本地化的图片到Xcode中/或者自定义的文件下统一处理这些需要本地化的图片
      • 在Localizable.strings文件下相应文件中设置key-value,通过NSLocalizedString(key,comment)来获取相应的字符串,然后根据这个字符串再获取图片。
      NSString *imageName = NSLocalizedString(@"icon", nil);
      UIImage *image = [UIImage imageNamed:imageName];
      self.imageView.image = image;
      **缺点**
      1. 工作量很大
      2. storyboard/xib中不能直接使用,需要代码中判断重新取正确的图像名,并重新赋值
      
      • 或者**把这张图片当做InfoPlist.strings去处理, 即选中图片 - 点击Localize 这些操作 ** 。然后这个图片会变成文件夹模式,点击任意一个文件,找到文件所在位置,然后替换成你想要显示的文件即可(文件名保持一致)。
      **优点**
      就当做正常的图片使用即可。系统会根据语言设置找到对应的图片
      
    6. 查看/切换本地语言
      • 应用启动时,首先会读取NSUserDefaults中的key为AppleLanguages对应的value,该value是一个String数组,也就是说,我们访问这个名为AppleLanguages的key可以返回一个string数组,该数组存储着APP支持的语言列表,数组的第一项为APP当前默认的语言。
      NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
      NSString *currentLanguage = languages.firstObject;
      NSLog(@"模拟器当前语言:%@",currentLanguage);
      
      • 同理,既然我们可以通过AppleLanguages这个key从NSUserDefaults中取出语言数组,那么我们也可以给AppleLanguages这个key赋值来达到切换本地语言的效果,从此以后,我们就无需频繁的去模拟器的设置->通用->语言与地区 中切换语言
      // 切换语言前
      NSArray *langArr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
      NSString *language1 = langArr1.firstObject;
      NSLog(@"模拟器语言切换之前:%@",language1);
      
      // 切换语言
      NSArray *lans = @[@"en"];
      [[NSUserDefaults standardUserDefaults] setObject:lans forKey:@"AppleLanguages"];
      
      // 切换语言后
      NSArray *langArr2 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
      NSString *language2 = langArr2.firstObject;
      NSLog(@"模拟器语言切换之后:%@",language2);
      
      • 与第三条中的最后一条相对比,其实本质上就是给NSUserDefaults中名为AppleLanguages的key赋值
      • 还有一种方式如下图
        images
      • app内的语言切换。一个App切换语言的Demo
    7. storyboard/Xib 的本地化
      • 在这个Xib/storyboard文件,完成的差不多的时候,对他进行本地化,无外乎,点中文件,Xcode右侧本地化操作,操作步骤与上面类似
      • 本地化后,在有所改变,已经本地化的文件不会变化,所以需要随时更新。一个笨的方法就是,去掉勾选的English和Chinese,然后会提示remove->选中delete选项,然后在勾选English和Chinese,然后会重新生成
      • 友情提示,在Xib/storyboard中生成的文件中,主要使用ObjectID,先删除然后重新生成,同一个控件的ObjectID不会发生变化。这样就可以记录之前的,然后对最新的略微改变即可。
      /* Class = "UILabel"; text = "国际化测试"; ObjectID = "knJ-x1-3Rk"; */
      "knJ-x1-3Rk.text" = "国际化测试";
      
    8. 脚本
    9. 第8项的脚本适应用Excel表格数据与配置文件的转化。本项的适用于,项目工程开始很久后,突然想要国际化配置,整个工程很多地方都需要处理。
      • 第一项代码中的待处理项

        • 如果你最开始就在代码中已经预先设置了NSLocalizedString(@"使用帮助", nil)类似的字段,只差生成对应的key-value时,你可以
          首先切换到需要处理的目录下
          cd ****
          其次创建对应的文件
          mkdir zh-Hans.lproj
          mkdir en.lproj
          最后查找目录下后缀为.m的文件,然后生成对应的数据存储到对应文件夹下
          find ./ -name *.m | xargs genstrings -o en.lproj
          find ./ -name *.m | xargs genstrings -o zh-Hans.lproj
          
      • 如果你什么也没配置,就是简单的将相关展示文字设置为对应的中文字符

        • 首先你需要全局替换需要配置的中文字符,并以已经设置的中文字符为key
          首先以正则表达式: (@"[^"]*[\u4E00-\u9FA5]+[^"\n]*?")\s* 来全局查找类似于 @"我的" 这个格式的字符
          然后在工程中 点击搜索框 -> 替换Find 为 replace, 然后点击紧挨着的text 替换为Regular Expression
          上面输入:(@"[^"]*[\u4E00-\u9FA5]+[^"\n]*?")\s*
          下面输入:NSLocalizedString\($1\, nil)
          中间的in ** 你可以点击一下后,选择你需要处理的文件夹
          最后开始替换
          
        • 随后你就可以参考上一个选项进行处理, 或者你可以使用 iOS 多语言版本的开发(三)这个教程中的工具进行处理
        • 简单的使用以上基本包括,更复杂的使用,例如:动态字体,日期展示,数字展示等相关的,请查看字符串本地化这篇介绍。
      • 第二项是xib或者storyboard中的待处理项

        • 首先就是基础操作,对每个需要进行配置的xib文件,仿照第7项操作。即手动开启每个的本地化。
        • 然后就是对这些xib的自动化更新配置了。即每次如果xib有改动,需要更新本地化数据时。让其自动化处理。脚本代码文件。原始操作流程参考iOS国际化详解
        • 简单步骤描述
          • 将存放脚本文件的文件夹,导入脚本文件到项目的根目录

            脚本文件夹 RunScript/AutoGenStrings.py
            导入到     Desktop/cf-ios/CF/RunScript/AutoGenStrings.py
            Desktop桌面, cf-ios 工程所在的文件夹名字, CF为工程名字
            
          • 选择项目 -> targes -> Build Phases -> + -> New Run Script Phase,将下面代码copy到对应的路径

            #!/bin/sh
            python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}
            
            详细步骤参考
          • Build Setting -> Deployment -> Deployment Location / Deployment Postprocessing -> Yes

            详细步骤参考
          • 注意文件路径中不能拥有空格,否则Xcode脚本会找不到文件的错误

          • 注意开启了Deployment Location / Deployment Postprocessing 后,会导致工程无法调试(debug),关闭后即可

          • 注意运行后可能出现This app could not be installed at this time.提示,关闭Deployment Location / Deployment Postprocessing设置,然后clean工程,重新运行即可。如果这个方式无法解决,可以尝试重启Xcode, 清楚模拟器的缓存或者重启模拟器。

          • 重点需要时在开启,不需要时请关闭,防止意外情况。

    参考资料
    简书:VV木公子
    简书:iOS 国际化的设置大全
    简书:iOS App的国际化,以及App内的语言切换
    简书:iOS国际化
    iOS国际化——通过脚本使storyboard翻译自增

    简书:iOS国际化详解
    简书:本地化 genstrings
    很全的介绍:字符串本地化
    iOS 多语言版本的开发(一)
    iOS 多语言版本的开发(二)
    iOS 多语言版本的开发(三)
    iOS10权限声明国际化
    Info.plist的秘密(raywenderlich笔记)
    plist字段列表,很全

    相关文章

      网友评论

        本文标题:国际化

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