macOS 开发之代码字符串的本地化

开发了一款好用的 macOS app 后,为了让更多人的尝到自己 “真香” 的作品,app 的国际化和本地化是有必要的,app 的本地化分三部曲讲解,本文是第三部:代码字符串本地化。

第一部传送门:macOS 开发之 APP 名称本地化

第二部传送门:macOS 开发之 storyboard 或 xib 本地化

实现平台

  • macOS 10.14.3
  • swift 4.2.1
  • xcode 10.1

准备工程

本文直接使用上一篇文章macOS 开发之 storyboard 或 xib 本地化的工程,点我下载!

为了展示本文要讲的内容,这里利用已有的 label,另外添加两个按钮来切换 label 的内容。

添加按钮

打开上面下载的工程,打开 Main.storyboard 可以看到 View controller 中已经有一个 label ,本小节添加两个按钮,并添加相应的点击 action。

  1. 按下快件键 Shift + Command + l 键,打开控件选择器,搜索框输入 button 就会筛选出所有的按钮控件,将其中的 Gradient Button 拖入 View Controller,调整其大小为 50 * 232,靠左放置到合适位置,打开 Attributes Inspector(选中按钮,按组合键 Option + Command + 4),其中勾选 Transparent ,Image 选择 NSGoForwardTemplate,然后勾选 Refuse First Responder

  2. 同样的方法添加第二个按钮(或者直接复制第一个按钮),不过是靠右放置,Attributes Inspector 中更改 Image 为 NSGoBackTemplate,其它设置与第一个按钮一致

  3. 按下快捷键 Option + Command + 回车键会显示 Main.storyboard 中 view controller 对应的 Assitant Editor 并打开对应的 swift 文件

  4. 选中第一个按钮,按住 Ctrl 键,鼠标左键按住拖动至 Assitant Editor 中松手添加一个 Action ,名称为 previousLabel

  5. 选中第二个按钮,按住 Ctrl 键,鼠标左键按住拖动至 Assitant Editor 中松手添加一个 Action ,名称为 nextLabel

上述五步操作,可参考如下视频进行:

添加 Label 的 outlet

打开 Main.storyboard ,选中 view controller 中的 label,按下快捷键 Option + Command + 回车键会显示 Main.storyboard 中 view controller 对应的 Assitant Editor 并打开对应的 swift 文件,按住 Ctrl 键,在 label 上按住鼠标左键拖动到 Assitant Editor 中松手添加一个 outlet ,名称为 movieLabel

添加标签内容

在 ViewController.swift 的 ViewController 类中添加以下定义:

let movies = ["天空之城", "幽灵公主", "风之谷"]
var movieIndex = 0

在 ViewDidLoad 方法的 super.viewDidLoad() 后面添加:

movieLable.stringValue = movies[movieIndex]

完善按钮的 action

补充 previousLabelnextLabel 的实现:

@IBAction func previousLabel(_ sender: Any) {
    movieIndex -= 1
    if movieIndex < 0 {
        movieIndex = movies.count - 1
    }
    movieLable.stringValue = movies[movieIndex]
}

@IBAction func nextLabel(_ sender: Any) {
    movieIndex += 1
    if movieIndex >= movies.count {
        movieIndex = 0
    }
    movieLable.stringValue = movies[movieIndex]
}

代码本地化

代码中字符串的本地化需要新建一个名为 Localizable.strings 的文件,新建过程类似于macOS 开发之 APP 名称本地化InfoPlist.strings的过程,代码中的字符串如果需要本地化必须在这个文件中定义。

添加本地化文件

  1. 按下快捷键 Command + n 打开新建文件的导航窗口,选中 macOS - Resources - Strings file,next, 更改名称为 Localizable.strings

  2. 此时会打开文件,按下快捷键 Option + Command + 1 就会打开其 file Inspector,可以看到分组 Localization 中的 Localize... 按钮,点击这个按钮就会跳出弹窗:

  3. 选择 English 选项,点击 Localize 就会发现 InfoPlist.strings Inspector 中的 Localizations 分组变成了三个勾选框,其中 English 是勾选的,这里也把 Chinese 和 Japanese 勾选上,此时你会发现 Xcode 左侧工程导航栏 InfoPlist.strings 左侧出现了一个小三角,点开就会发现其变成了与三种语言对应的三个 Strings 文件:

代码字符串的本地化

代码中字符串的本地化需要两步,一是在刚新建的 String 文件中添加字符串定义,二是调用方法 NSLocalizedString(forKey:, comment:) 根据字符串定义的键获取字符串。

添加本地化字符串定义

因为代码中只在 movies 初始化中使用了字符串,所以对应要定义一下它们,分别在三个 Strings 文件中定义。

  • Localizable.strings (English):
"movie-label-1.title" = "Laputa Castle in the Sky";
"movie-label-2.title" = "Princess Mononoke";
"movie-label-3.title" = "Nausicaa Of The Valley Of The Wind ";
  • Localizable.strings (Chinese(Simplified)):
"movie-label-1.title" = "天空之城";
"movie-label-2.title" = "幽灵公主";
"movie-label-3.title" = "风之谷";
  • Localizable.strings (Japanese):
"movie-label-1.title" = "天空の城ラピュタ";
"movie-label-2.title" = "もののけ姫";
"movie-label-3.title" = "風の谷のナウシカ";

更新代码

修改添加本地化字符串对应的地方,也就是 movies 初始化的地方,修改为:

let movies = [NSLocalizedString("movie-label-1.title", comment: ""),
              NSLocalizedString("movie-label-2.title", comment: ""),
              NSLocalizedString("movie-label-3.title", comment: "")]

效果展示

更改系统语言查看各语言的效果。

  • English

  • Chinese(Simplified)

  • Japanese

添加新的本地化字符串

macOS 开发之 storyboard 或 xib 本地化 中提到了一个工具 BartyCrouch,它的子命令 code 可以帮助我们自动扫描代码中调用 NSLocalizedString(forKey:, comment:) 的地方,如果 Localizable.strings 中没有的字符串键会自动追加,非常方便!

⚠️:

bartycrouch 已经发布了 4.0.0,使用方法不同,这里展示的方法只适用于 bartycrouch v3.x.x 版本,后续十里会出一篇关于 bartycrouch v4.0.0 的使用教程,请持续关注博客 和 知乎专栏 macOS 开发

所以我们在之后若要将要使用的字符串本地化,直接使用 NSLocalizedString(forKey:, comment:) 方法,同时定义一个新的 key 先用上,之后去命令行使用 bartycrouch code 就可以添加新的字符串定义,只需要再修改 Strings 文件中新加键的值就可以了。

举例说明

  • 比如再在 movies 初始化中新加一个元素,代码可写为:
let movies = [NSLocalizedString("movie-label-1.title", comment: ""),
              NSLocalizedString("movie-label-2.title", comment: ""),
              NSLocalizedString("movie-label-3.title", comment: ""),
              NSLocalizedString("movie-label-4.title", comment: "")]
  • 命令行下切换至工程文根目录,执行命令:
# -p 指定包含工程代码文件的目录 ,-l 指定可以搜到 Localizable.strings 文件的代码目录
$ bartycrouch code -p InternationalDemo -l InternationalDemo
ℹ️ BartyCrouch: Successfully updated strings file(s) of Code files.
  • 打开三个 Localizable.strings 文件会发现新添加了一项,并且为每一个添加了预置注释:
/* No comment provided by engineer. */
"movie-label-4.title" = "";
  • 分别为三个 Strings 文件修改对应新加项的值:
"movie-label-4.title" = "Howl's Moving Castle";
"movie-label-4.title" = "哈尔的移动城堡";
"movie-label-4.title" = "ハウルの動く城";

运行程序,可以看到不同语言下,第四个电影就出现了!

编译时更新

macOS 开发之 storyboard 或 xib 本地化 中在工程中创建了 build phase 运行脚本,脚本中添加代码字符串本地化要执行的命令即可:

# Type a script or drag a script file from your workspace to insert its path.
if which bartycrouch > /dev/null; then
    bartycrouch interfaces -p .
    bartycrouch code -p . -l .
    bartycrouch lint -e -d -p .
else
    echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
fi

至此,您应该学会如何对代码中字符串本地化了吧!

此部分完成后的工程下载:InternationalDemo3