Featured image of post 给 Xcode 27 做汉化:XcodeZH 1.0.5 安装教程与开发手记

给 Xcode 27 做汉化:XcodeZH 1.0.5 安装教程与开发手记

为什么要做、怎样一键安装、开发过程走过哪些弯路,以及这个实验项目目前仍有哪些边界。

我每天都要打开 Xcode。新建项目、改签名、找构建设置、配快捷键、处理软件包依赖,这些操作几乎天天都会碰到。英文界面用久了也能熟悉,可熟悉并不等于方便。尤其是刚接触 Apple 开发时,很多时间并没有花在写代码上,而是在反复确认某个菜单、说明或设置到底是什么意思。

我先去网上找了一圈。严格说来,Xcode 并不是从来没人汉化过。Xcode 9 时代就有过中文语言包项目,但那套资源面对的是多年前的 Xcode,放到 Xcode 27 上已经不能直接用。现在的 Xcode 同时用了传统资源、插件元数据、SwiftUI 字面量、富文本和私有模型。单纯复制一个 Chinese.lproj 文件夹,只能汉化很小一部分界面。

没找到适用于当前版本、出问题后又能恢复的现成方案,我就决定自己做。项目现在叫 XcodeZH。

源码在 brucewong666/Xcode-zh,安装包可以从 XcodeZH 1.0.5 Experimental 下载。下面的命令、校验值和开发记录都以这个版本为准。

XcodeZH 现在能做什么

XcodeZH 是一个非官方的实验性简体中文工具,当前版本是 1.0.5-experimental,面向 Xcode 27 和 Beta。能走资源系统的文字,工具会写入汉化副本的 zh-Hans 资源;Apple 没有提供本地化键的固定界面文字,则由本地运行时词典精确替换。

这不是联网翻译。界面文字不会发给第三方服务,运行时只会查本地的 translations.json。词典里没有的内容,依然显示英文。

工具也不会修改 /Applications/Xcode.app 原版。它先建立一个 APFS 克隆,正式版默认放在 /Applications/Xcode-ZH.app,Beta 默认放在 /Applications/Xcode-beta-ZH.app。安装、汉化、恢复和删除都只对带有 XcodeZH 管理标记的副本生效。

项目 当前情况
版本 1.0.5-experimental
完整验证环境 Apple Silicon、Xcode 27.0 beta 4、Build 25183.64.12
本地词典 1419 条人工审校翻译
自动检查 12 项 Python 单元测试、457 个项目模板基线检查
原版 Xcode 不修改,只操作带管理标记的 APFS 克隆

它的完整流程是这样的:

/Applications/Xcode.app
        ↓ 建立 APFS 克隆
/Applications/Xcode-ZH.app 或 Xcode-beta-ZH.app
        ├─ 安全模式:写入 zh-Hans 资源
        └─ 实验模式:探针通过后加载本地翻译层
        ↓ 正常退出或中断
恢复安全签名并检查 entitlement

使用前先看边界

我完整验证过的环境是 Apple Silicon、Xcode 27.0 beta 4、Build 25183.64.12。测试机的 SIP 原本就是关闭的,XcodeZH 没有修改这个设置。SIP 保持开启时,安全资源模式和实验运行时层还需要更多实机验证。如果系统阻止加载,工具会停止并保留日志,不会尝试降低整台 Mac 的安全设置。

不要只为了汉化界面去关闭 SIP。

实验模式需要临时调整汉化副本的签名和最小 entitlement,这样才能加载在本机编译的翻译层。正常退出 Xcode,或启动器收到中断信号后,工具会恢复安全签名,并确认实验 entitlement 已经清除。使用实验模式时,启动它的终端窗口不能关闭。

还有一点需要提前说明:XcodeZH 做不到 100% 汉化。私有框架动态拼接的文字、绘制阶段直接生成的 SwiftUI 文本、还没审校的句子和技术专名,都可能保留英文。

一条命令安装并启动

打开 macOS 的“终端”,粘贴下面这条命令,然后按回车:

/bin/bash -c "$(/usr/bin/curl -fsSL https://raw.githubusercontent.com/brucewong666/Xcode-zh/main/install.sh)"

安装脚本会:

  1. 从 GitHub Release 下载 XcodeZH-1.0.5-Experimental.zip
  2. 核对文件的 SHA-256,校验值不一致就立即停止。
  3. 将完整工具安装到 ~/Applications/XcodeZH
  4. 启动 XcodeZH.command,进入操作菜单。

如果 ~/Applications/XcodeZH 已经存在,安装器会先把旧目录重命名为带时间的备份,不会直接删除。

如果不习惯直接运行网络脚本,可以先在仓库里查看 install.sh。确认内容没问题后再执行,也可以按下面的步骤手动安装。

手动安装

  1. 打开 Release 页面

  2. 下载 XcodeZH-1.0.5-Experimental.zip

  3. 解压完整文件夹。不要只复制里面的 .command 文件,词典、运行时源码和验证脚本都在同一个目录里。

  4. 如果脚本没有执行权限,在终端运行:

    chmod +x /你的路径/XcodeZH-1.0.5-Experimental/XcodeZH.command
    
  5. 双击 XcodeZH.command,先选择正式版或 Beta,再选择要执行的操作。

Release ZIP 的 SHA-256 是:

f1eb5f25c2c2a8298eeffbfb0bbec8669a00166efc30062d679d2fe10631bfc7

在终端中也可以自己核对:

shasum -a 256 XcodeZH-1.0.5-Experimental.zip

三种模式怎么选

模式 适合什么情况 当前取舍
安全资源汉化 想先体验菜单和传统资源汉化 更保守,但 SwiftUI 等界面仍会保留较多英文
实验运行时汉化 希望覆盖欢迎页、设置和更多固定界面文字 覆盖更多,需要探针、签名和退出清理流程
只读研究扫描 适配新 Xcode Build 或继续补词典 不修改 Xcode,只生成统计与未命中日志

安全资源汉化

安全模式会把英文 .lproj 复制成 zh-Hans.lproj,再翻译能够解析的 .strings.stringsdict。它还会处理插件显示字段和项目模板显示字段,但处理范围受白名单限制。

这个模式不加载运行时动态库,所以相对保守。代价也很明显:Xcode 27 里那些由 SwiftUI、富文本和私有模型生成的界面,仍然会有不少英文。

实验运行时汉化

实验模式会先运行 SwiftUI ABI、内存和菜单探针。只有探针全部通过,启动器才会加载本机编译的翻译层。这种方式可以覆盖菜单、欢迎页、设置页、快捷键标题、部分构建设置和其他非编辑控件。

运行时只替换词典中完全匹配的固定文字。源代码编辑器、控制台、项目名、路径、构建值和正在编辑的输入框都不在替换范围内。

只读研究扫描

扫描模式只统计语言资源、可解析文件、词典命中、编译 NIB 和其他候选内容,不会修改 Xcode。适配新版本时,我会先用它看看新 Build 变了什么,然后再根据未命中日志补词典。

命令行用法

进入 XcodeZH 目录后,可以直接运行:

./XcodeZH.command --install beta
./XcodeZH.command --safe beta
./XcodeZH.command --experimental beta
./XcodeZH.command --scan beta
./XcodeZH.command --status beta
./XcodeZH.command --restore beta
./XcodeZH.command --remove beta

把第二个参数从 beta 改成 stable,就会操作正式版 Xcode。

第一次使用时,建议先运行“检查状态”,再选安全模式或实验模式。开始前要完全退出对应的 Xcode 汉化副本。如果看到“请先完全退出 Xcode-ZH.app”,说明进程还在运行,退出后重新执行即可。

恢复和删除

“恢复干净克隆”会根据当前的原版 Xcode 重新建立汉化副本。当原版和副本的 Build 不一致时,工具会拒绝增量修改,这时也应该用干净恢复。

“删除汉化副本”只会处理带有 XcodeZH 管理标记的副本,不会删除原版 Xcode,也不会碰用户项目。

如果实验模式因为断电或强制结束进程,没有机会正常清理,下次使用前先运行“检查状态”。工具会检查签名和 entitlement。如果它无法确认当前状态安全,不要直接启动副本,先选“恢复干净克隆”。

开发过程比我预想的复杂

最开始的想法很简单:找到 Xcode 的英文资源,复制一份中文资源,再把字符串逐条翻译。这个方法的确能让一些菜单和传统界面变成中文,但很快就到头了。

Xcode 27 的文字并不全在 .strings 文件里。有些来自插件元数据,有些写在项目模板的 TemplateInfo.plist 中,还有一些是 SwiftUI、AttributedString 或私有模型直接生成的。编译后的 NIB、NULLcanary 和部分内部资源也不适合直接改。硬改不一定能多翻译几个词,反而可能让 Xcode 无法启动。

项目早期还处理过文本形式的 .xcspec。后来实测才发现,Xcode 27 根本不读取那些文本镜像。现在的版本会从相同 Build 的原版恢复全部 .xcspec,不再把这些无效修改留在副本里。

运行时层也走过弯路。旧版为了应对 SwiftUI 页面重建,每两秒扫描一次非编辑界面。这样做以后,切换页面时偶尔会先看到英文,等一下才变成中文。1.0.5 改为由界面创建、窗口更新和窗口激活事件触发,大部分文字第一次出现时就会处理。现在仍保留了 0.5 秒的低频扫描,专门补上少数私有 SwiftUI 的漏报。

我还试过直接回写文件模板选择器的私有控件。命中的词条的确更多了,但 Xcode 主进程也在实测中直接中止。这条路后来被完整撤回,只留下只读、精确匹配并通过探针的处理。少几处中文总比把编辑器弄崩好。

为什么不用实时机器翻译

开发工具里的同一个英文词,换个位置就可能是另一个意思。TargetSchemeSigningCapability 这些词脱离上下文后直接翻译,很容易得到读起来通顺、实际上却不符合开发习惯的结果。实时翻译还可能误碰项目名称、代码、控制台输出和用户输入。

所以 XcodeZH 用了一个慢一些的办法:人工审校词典,按原文精确匹配,同时限制调用方和控件范围。1.0.5 的词典共有 1419 条。技术名、平台名、设备名、项目名和没审校过的文字,我宁愿先保留英文。

词典的增长会比自动翻译慢,但每一条替换都可以检查、复现和撤销。这个取舍我目前不打算改。

怎么确认没有改坏 Xcode

当前版本会运行 12 项 Python 单元测试,也会检查 SwiftUI 和 AttributedString 注入探针、ABI、日志去重和内存压力。处理项目模板时,工具先从原版建立基线,只允许修改显示白名单中的字段,再核对占位符和非显示字段没有变化。

1.0.5 已检查 457 个内置 TemplateInfo.plist。运行时退出后,还会确认实验 entitlement 为空,并执行深度签名验证。

我实测过的界面包括顶部核心菜单、欢迎页、设置侧栏、导航、位置、编辑、Apple 账户、行为和快捷键。导航器连续切换,以及“导航、位置、导航”的往返切换也做过检查,已翻译的内容不会轻易掉回英文。

这些检查只能尽量减少已知风险,不会让一个实验项目变成 Apple 官方组件。Xcode 或 Swift 更新后,私有结构仍然可能发生变化。所以探针失败时,工具会直接停止。

目前的局限

局限 对使用者意味着什么
汉化不完整 私有框架动态拼接、绘制阶段直接生成的 SwiftUI 文本和词典未收录内容仍会显示英文
兼容性与 Xcode Build 有关 新 Beta 或正式版发布后,需要重新扫描和验证
实验层依赖 Swift ABI 启动器会先跑探针,失败时不会加载完整运行时层
SIP 开启环境验证不足 工具不会替用户修改 SIP,也不会引导自动关闭
主要验证设备是 Apple Silicon 其他硬件能运行脚本,不代表已经完成同等程度的验证

遇到问题时看哪里

工具日志在:

~/Library/Logs/XcodeZH/

运行时命中、未命中和状态记录在:

~/Library/Application Support/XcodeZH/<beta|stable>/

反馈问题时,最有用的信息是 Xcode 版本、Build、Mac 芯片、所选模式、出问题的页面截图和操作路径。完整日志里可能带有项目代码、个人账户或私密路径,上传前先检查,删掉与问题无关的部分。

后面还会继续做

1.0.5 不是终点。接下来要做的事都很具体:适配新的 Xcode Build,根据未命中日志补词典,在更多 Mac 和 SIP 开启环境中验证,减少运行时层的等待感,也会继续改安装、更新、恢复和卸载流程。

有几条线不会因为追求覆盖率而放宽:不改原版 Xcode,不碰用户代码,不用联网机器翻译,也不往没验证过的私有模型里写内容。

我做 XcodeZH,只是想少在英文界面里停顿几次,也让刚入门的中文开发者更容易找到设置。它现在还有不少英文,也只在有限环境中做过完整验证,所以版本名里仍然留着 Experimental。源码、测试、Release 和校验值都已公开,用之前可以先看清楚它做了什么,再决定要不要安装。