关于我:大厂摸鱼 + 业余独立开发,之后会输出深度技术文章 + 独立开发技巧

我的往期技术文章合集:RickeyBoy – Gitbub

我的独立开发 App:iColors – 规划创意 配色助手

上一篇:

独立开发之 App 国际化全过程(一):为什么要做国际化

独立开发之 App 国际化全过程(二):App 数据翻译

独立开发之 App 国际化全过程(三):Core Data 模型晋级

独立开发之 App 国际化全过程(四):Core Data 模型解析

独立开发之 App 国际化全过程(五):提取 App 中文本案牍

替换代码中运用的文本

好的,前文咱们提取了一些带翻译的文件,详细翻译的过程咱们就跳过了。现在假设咱们可以经过某种方法得到详细的翻译后的结果。

那么在此根底之上,咱们需求先优化一下 Localizable.strings 的声明方法

Localizable.strings 运用专门的 Key

上一部分咱们在 Localizable.strings 文件中增加了对应的翻译,如下图所示:

// Localizable (Chinese, Simplified)
"颜色主题" = "颜色主题";
// Localizable (English)
"颜色主题" = "Editor's Pick";

可是这样有一个小问题,便是对于中文(之前的默认言语)来讲,无法区别是否是处理过的翻译。比方我现在在代码中有一个相似的运用之处,我并没有方法一眼识别出,这是否是经过多言语处理过的。

Text("首页")

以及别的一个问题,咱们有些时分会存在同样的中文,却因为详细运用场景不同,而需求对应不同的英文。比方同样是”会员”,有些可能需求依据运用场景、UI 界面等不同因素,翻译成 “vip” 或者是 “membership”。这样假如直接用中文自身作为 key,就会产生问题。

所以,咱们最好的方法还是运用独自的 Key,这样可以更标准和更准确。比方下面这样:

// Localizable (Chinese, Simplified)
"SOME_KEY" = "颜色主题";
// Localizable (English)
"SOME_KEY" = "Editor's Pick";

这样,咱们需求手动去替换一下运用就可以了。

Text("SOME_KEY")

至于这儿运用的 KEY,只需求确保唯一性就可以了,与此同时假如能有必定的字面含义会更好。详细的生成可以交给 ChatGPT,可以节约不少的时间。

在代码中运用 Key

好的,接下来便是我自己以为最爽的时刻了,那便是替换代码中文本案牍的运用。首先,假如是 Text、Button 等体系提供的组件,是可以直接承受 Key 的:

// 直接运用 key
Text("SOME_KEY")
Button("SOME_KEY", role: .cancel) { ... }

咱们想想,为什么这儿直接运用 “SOME_KEY”,展示的是多言语结果,而不是直接将 “SOME_KEY” 作为字符串展示出来呢?

来自 SwiftUI 文档的解说:

When you use the initializer Text("Hello"), SwiftUI creates a LocalizedStringKey for you and uses that to look up a localization of the Hello string. This works because LocalizedStringKey conforms to ExpressibleByStringLiteral.

能做到这一点,本质上是因为这些组件都默认完成了经过 LocalizedStringKey 作为参数进行初始化,SwiftUI 会自动经过 “SOME_KEY” 创立 LocalizedStringKey 完成多言语,而不是运用一般的 String。

extension Text {
    public init(_ key: LocalizedStringKey, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil)
}

没错,这儿的 “SOME_KEY” 会被创立为 LocalizedStringKey 类型,而不是 String 类型!

了解了这一点,相应的咱们假如自定义一个 CustomView,就需求运用 LocalizedStringKey 而不是 String

// 声明
struct CustomView: View {
    let title: LocalizedStringKey
    var body: some View {
        Text(title)
    }
}

当然咱们也可以手动将 String 转变为 LocalizedStringKey,比方像下面这样声明

// 声明
struct CustomView: View {
    let some_key: String
    var body: some View {
        Text(LocalizedStringKey(some_key))
    }
}

检查遗失的翻译

好了,当咱们替换了一切多言语的运用之后,现在来处理之前遗留的一个问题:假如发现忘记进行多言语的文本案牍?

此刻咱们统一运用 “SOME_KEY” 的优点就体现出来了,咱们只需求检查没有直接运用中文字符串的当地即可,因为正确情况下,咱们一切的代码中都不会直接呈现中文字符串,只会呈现 “SOME_KEY”!

下面便是检查脚本,假如有遗失的翻译,就会被直接打印出来。原理很好了解,我会用注释尽量讲清楚:

import os
import unicodedata
​
project_directory = "xxxxx"# 判断字符串中是否包含中文
def contains_chinese_characters(string):
  for char in string:
    if 'CJK' in unicodedata.name(char, ''):
      return True
  return False# 判断是否是注释内容,假如是注释内容的话可以忽略
def is_comment(line):
  line = line.strip()
  return line.startswith("//") or line.startswith("/*") or ("//" in line and contains_chinese_characters(line.split("//")[1]))
​
# 用于统计结果
violations = []
​
# 遍历一切文件
for root, _, files in os.walk(project_directory):
  for file in files:
    if file.endswith(".swift"):
      file_path = os.path.join(root, file)
      with open(file_path, "r") as f:
        lines = f.readlines()
        for line_number, line in enumerate(lines, start=1):
          # 假如不是注释,且包含中文,就记录下来
          if not is_comment(line) and contains_chinese_characters(line):
            violations.append((file_path, line_number, line.strip()))
​
# 输出
if violations:
  print("Violations:")
  for violation in violations:
    file_path, line_number, line = violation
    print(f"File: {file_path}, Line: {line_number} - String: {line}")
else:
  print("No violations found.")

这样,咱们遗失的部分就能被轻松找出来了。比方会输出:

File: /.../xxxx.swift, Line: 38 - String: AlertToast(type: .regular, title: "保存失利")

检查对应的代码,是我直接运用第三方组件的部分,之前就没有被自动提取出来:

// 弹出失利提醒
AlertToast(type: .regular, title: "保存失利")

Tips:全局替换剩余的 LocalizedStringKey

咱们之前提到,SwiftUI 可以自动识别出 “SOME_KEY”,并协助咱们创立 LocalizedStringKey,然后完成多言语。不需求手动进行额定的创立。这一个优势不仅包含 Text、Button,也包含 navigationTitle、toggle 等,也都是可以自动识别的。

// 没必要
Text(LocalizedStringKey("SOME_KEY"))
// ✅
Text("SOME_KEY")

这样就可以大大简化咱们的代码。不过可能有一些开发者,在最开端完成的时分并不知道这一个技巧,或者现在读了文章之后才知道这个技巧,那该怎么办呢,莫非要一个一个当地手动修正吗?

当然咱们还有更好的方法,便是运用 Xcode 的正则匹配搜索,来进行批量的替换!

独立开发之 App 国际化全过程(六):替换代码中运用的文本

如图所示就可以了,两个正则表达式也很好了解,我直接贴在这儿,供大家参阅

// Text(LocalizedStringKey("SOME_KEY"))
Text(LocalizedStringKey("(.+?)"))
// Text("SOME_KEY")
Text("$1")

本篇解说了如何将翻译后的内容嵌入在代码中,实操内容比较多!下一篇会持续解说如何完成言语切换