关于我:大厂摸鱼 + 业余独立开发,之后会输出深度技术文章 + 独立开发技巧
我的往期技术文章合集:RickeyBoy – Gitbub
我的独立开发 App:iColors – 规划创意 配色助手
上一篇:
独立开发之 App 国际化全过程(三):Core Data 模型晋级
替换代码中运用的文本
好的,前文咱们提取了一些带翻译的文件,详细翻译的过程咱们就跳过了。现在假设咱们可以经过某种方法得到详细的翻译后的结果。
那么在此根底之上,咱们需求先优化一下 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 aLocalizedStringKey
for you and uses that to look up a localization of theHello
string. This works becauseLocalizedStringKey
conforms toExpressibleByStringLiteral
.
能做到这一点,本质上是因为这些组件都默认完成了经过 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 的正则匹配搜索,来进行批量的替换!
如图所示就可以了,两个正则表达式也很好了解,我直接贴在这儿,供大家参阅
// Text(LocalizedStringKey("SOME_KEY"))
Text(LocalizedStringKey("(.+?)"))
// Text("SOME_KEY")
Text("$1")
本篇解说了如何将翻译后的内容嵌入在代码中,实操内容比较多!下一篇会持续解说如何完成言语切换