构建停在 CompileStoryboard 或 CompileXIB,最后只显示 Build Failed?
本周建议:先从日志确认是否真是 Interface Builder 编译失败,再对照同一项目的 toolchain 与 simulator 模式;只有回退后错误消失,才把新模式列为排查线索,别先重装 Xcode 或删除模拟器。 Apple 确认 Xcode 27 为 UIKit(Cocoa Touch)文档默认启用 toolchain 编译模式,并提供 simulator 回退入口。(Apple Xcode 27 Release Notes)

这篇适合维护 UIKit Storyboard 项目、升级后构建失败的独立开发者,以及需要检查 XIB 编译证据的小团队。
如果你在远程 Mac 或 macOS CI 构建,还可以按同一套证据核对环境差异,而不是先把所有失败都归因于工具链。

先判定失败阶段:Interface Builder 还是后续构建?

不要只看最终的 Build Failed。构建由多个任务组成,Storyboard、XIB、Swift 编译、链接和脚本阶段的失败原因不同;应在构建日志中找到第一个有效错误,并确认它关联的操作和文件。Apple 的构建系统说明介绍了 Xcode 如何根据项目输入安排构建任务;构建失败日志排查说明也建议查看失败操作的日志。

日志中首先出现的失败对象 你应检查什么 暂时不要据此判断
CompileStoryboard、.storyboard 或 ibtool 具体 Storyboard 文件、目标及 Cocoa Touch 编译模式 模拟器运行时是否已下载
CompileXIB、.xib 或 ibtool 对应 XIB、其所属目标和 Interface Builder 编译输出 整个项目中的所有 XIB 都有相同问题
Swift 编译、链接或脚本任务 对应源文件、依赖或脚本的首个错误 这是 Interface Builder 新模式故障
构建成功,之后启动或测试失败 运行时、设备目标、安装或测试日志 Storyboard 编译本身已经失败

开始改设置前,先记下 Xcode 版本、scheme、构建目标、配置名称、失败文件和完整错误原文。同一次构建可能包含多个 target;只记录最终摘要,容易把依赖 target 的错误误认成主 App 的问题。

怎么区分 XIB 和 Storyboard 编译错误?
看失败任务实际处理的文件类型和日志命令,不要只凭界面文件在工程中的位置判断。再到对应 target 的 Build Settings 核对:Apple 的Build Settings Reference分别列出 XIB 相关的 IBC_… 设置与 Storyboard 相关的 IBSC_… 设置;它们不是可以不分文件类型互换的同一项。

再核对 UIKit 文档与编译模式:不等于模拟器故障

Xcode 27 的新模式针对 UIKit(Cocoa Touch)Interface Builder 文档。Apple 说明,默认启用的 toolchain 模式可以在无需下载 Simulator的情况下编译这类文档,尤其面向构建服务器。遇到模式相关问题时,可对 UIKit 文档使用 simulator 模式作为退出路径。这个说明并不表示所有 UIKit 项目都会失败,也不表示模拟器安装、应用启动或运行时异常都由该模式导致。

对照项 默认 toolchain 模式 临时 simulator 模式
用途 按 Xcode 27 默认方式编译 UIKit Interface Builder 文档 排查新模式是否与当前故障相关
Simulator Runtime Apple 说明此模式无需下载 Simulator 使用前应确认项目所选目标及环境能完成对应构建
判断价值 可观察默认构建是否稳定 可作为对照结果,不是永久修复证明
设置入口 检查目标实际解析出的 build setting 可按目标设置 IBC_COCOATOUCH_COMPILER_MODE = simulator

Xcode 27 编译 Storyboard 失败,要先下载 Simulator Runtime 吗?
不要把下载运行时作为默认动作。若日志指向 UIKit Storyboard 的 Interface Builder 编译,先检查编译模式和报错文件;Apple 已明确说明 toolchain 模式的设计目标之一,就是不依赖已下载的 Simulator 来编译 Interface Builder 文档。若失败发生在运行、测试或其他阶段,再针对那个阶段检查目标和运行时条件。

核对设置名时要特别留心拼写。你可能会搜到 IBC_COCOATOOUCH_COMPILER_MODE 这个写法,但 Apple 文档列出的名称是 IBC_COCOATOUCH_COMPILER_MODE。Storyboard 的对应设置在 Build Settings Reference 中以 IBSC_COCOATOUCH_COMPILER_MODE 列出;先确认你改的是出错文件所属 target 的正确项。build setting 可在 Xcode 设置界面、配置文件和构建调用中配置,项目可能存在不同层级的值。

提醒: 如果日志首先报的是 Swift、链接、签名或脚本错误,先沿对应构建阶段排查。切换 Interface Builder 模式对这些错误没有明确诊断价值。

用同提交做模式对照:结果用于定位,不用于宣布修复

切换前保留默认模式日志,记录目标、配置、提交版本和错误文件;然后只改一个变量,在同一提交、同一目标上复测。若手动调用 ibtool,Apple 的回退参数是 --cocoatouch-compiler-mode simulator;不要把命令参数误当成整个项目的永久配置。遇到模式相关问题时,可先退出该模式,并提交反馈及相关 ibtool 错误。

如何把 toolchain 模式切回 simulator?
先确定失败的是哪个 target,再只对该 target 的 UIKit 文档设置 IBC_COCOATOUCH_COMPILER_MODE = simulator;若是单独调用 ibtool,使用 --cocoatouch-compiler-mode simulator。记录切换前后的日志。若希望把设置写进 .xcconfig,可参考 Apple 的构建配置文件说明,并明确绑定到需要验证的配置,避免无意影响其他目标。

按下面清单复测;每项都要能从日志或项目设置中核实:

  • [ ] 固定同一提交、scheme、target 和构建配置。
  • [ ] 保存默认模式下的完整构建日志,并标出首个有效错误。
  • [ ] 只切换出错 target 的 Cocoa Touch 编译模式,不同时改动文件或依赖。
  • [ ] 重新构建同一目标,保存 simulator 模式下的日志。
  • [ ] 对照两次构建的首个失败点、失败文件和实际执行的 Interface Builder 编译任务。
  • [ ] 若构建成功,检查预期构建产物是否生成;需要运行或测试时,再单独验证运行时结果。
  • [ ] 将回退范围、构建配置及复测结论记录下来,避免把临时绕过误写成全项目修复。

Apple 的构建计时说明介绍了查看构建任务信息的方式;如果问题确认只在特定构建任务出现,保留任务级记录有助于后续复核。若需要向 Apple 提交模式相关反馈,可参照其Xcode Cloud 反馈说明:提交前先检查日志和附件,移除不应分享的个人信息、凭据或项目内容。

远程 Mac 与 CI:对齐输入后再判断是不是工具链

远程构建失败时,不要只比较两台机器屏幕上显示的 Xcode 名称。你还要确认实际执行构建的账户、所选开发者目录、目标和 build settings 是否一致;并确认两边构建的是同一提交、同一 Storyboard/XIB 文件。账号权限、环境变量和目标差异都可能造成不同结果,单次远程失败并不能证明新模式是原因。

对照证据 本地构建 远程 Mac / CI 差异出现时的下一步
Xcode 与构建工具 记录实际使用的版本和路径 检查 CI 执行账户调用的版本和路径 先统一工具链,再做模式对照
项目输入 提交版本、scheme、target、文件 核对同一提交及相同构建目标 修正输入后重跑
Interface Builder 设置 查看出错 target 的解析值 查看远程实际解析值,不只看工程默认值 找出配置覆盖来源
首个错误及产物 保存日志与目标产物状态 保存对应任务日志与产物状态 比较同一任务的失败点

toolchain 模式对构建服务器的意义,是减少编译 UIKit Interface Builder 文档时对 Simulator 下载的依赖;它不是“远程构建必然成功”的保证。若默认模式失败、simulator 模式成功,且其他输入保持一致,这能支持“故障与编译模式有关”的判断,但仍要评估回退是否仅适用于一个 target,以及是否应向 Apple 报告。若两种模式的首个错误相同,回到文件内容、target 配置和工具链状态继续查,不要持续扩大回退范围。

若你需要一台独立、可持续访问的 macOS 环境来复现本地与远程构建差异,先核对项目的系统与 Xcode 条件,再查看 VMSPIN 远程 Mac 环境说明和套餐价格信息。远程环境适合临时复现或隔离构建;若你需要长期稳定的重负载机器、特定物理接口,或必须自行控制硬件,购买并维护本地 Mac 可能更合适。确定需要租用后,再从VMSPIN 方案入口确认可用选项;不要把租用环境当作修复日志中其他阶段错误的替代品。