磁盘空间被 Xcode 27 的 iOS Simulator Runtime 持续占用,打包机却只负责 Archive 和上传。

最快解法:只做编译、Release Archive、签名和 TestFlight 发布时,先不安装 iOS Simulator Runtime;需要运行 iOS 测试、UI Tests、SwiftUI Preview 或多系统回归时,再安装匹配版本,并优先把发布机与测试机分开。

适用人群与判断边界

如果你只想让远程 Mac 执行 Release Archive、代码签名和上传,可以按本文方法删除没有实际调用的模拟器组件。

如果你的 UIKit 项目包含 Storyboard 或 XIB,本文会重点说明 Xcode 27 的 Interface Builder toolchain 模式是否改变了组件依赖。

如果团队需要运行 iOS Simulator、XCTest UI Tests、SwiftUI Preview 或多个 iOS 版本的兼容测试,你应把本文当作环境拆分方案,而不是简单的“删除模拟器教程”。

截至 2026 年 9 月 5 日,Apple 的系统要求页面列出了 Xcode 27 beta 4,其要求为 macOS Tahoe 26.4 或更高版本;Xcode 27 仍处于 Beta 阶段,RC 和正式版的默认行为可能继续变化。请在每次 Beta、RC 或正式版更新后重新验收,不要把 Beta 行为当成永久承诺。Apple Xcode 系统要求

先按任务划分 Simulator Runtime

Xcode 27 打包机要装模拟器吗?答案不取决于项目是否“支持 iOS”,而取决于这台机器实际执行了什么 action、选择了什么 destination,以及构建脚本是否主动调用模拟器工具。

<
任务类型是否需要 iOS Simulator Runtime远程打包机建议验收证据
源码编译、面向真实设备的 Build通常不需要保留目标平台 SDK构建日志、产物架构
Release Archive通常不需要采用精简发布机.xcarchive、签名结果
TestFlight 上传与 Validate App通常不需要可与 Archive 共用Validate App 输出、上传记录
Storyboard / XIB 编译Xcode 27 默认不因资源编译而需要先验证 toolchain 模式界面资源编译日志
iOS Simulator 单元测试需要放到测试环境.xcresult
XCTest UI Tests需要单独安装 Runtime 和设备.xcresult、截图或日志
SwiftUI Preview需要可用模拟环境不放在精简发布机Preview 启动与交互结果
多版本、多设备布局回归需要对应 Runtime建立独立测试节点每个 destination 的测试结果
这里要分清四个对象:
  • 平台 SDK:用于面向 iPhone、iPad 等目标平台编译。
  • Simulator Runtime:提供模拟 iOS 系统运行环境。
  • 模拟设备:基于 Runtime 创建的具体设备实例。
  • iOS Simulator:实际启动和运行应用的模拟环境。
Apple 的组件文档把平台支持、可选组件和不同系统版本的模拟器 Runtime 分开管理,并允许你在 Xcode 设置或命令行中单独安装、删除。因此,下载了 Xcode,并不等于必须下载所有 Runtime。[Apple:下载和安装额外 Xcode 组件](https://developer.apple.com/documentation/Xcode/downloading-and-installing-additional-xcode-components?changes=la_4_5_9&language=objc)

发布机维护者:保留 Archive 所需组件

纯发布任务的最小边界

对于只做发布的独立开发者,打包机应优先保留:

  1. 与项目匹配的 Xcode 27 版本;
  2. 项目部署目标所需的平台 SDK;
  3. xcodebuildxcrun 等随 Xcode 提供的命令行工具;
  4. 签名证书、私钥、Provisioning Profile 或自动签名所需的账户权限;
  5. 项目脚本显式依赖的额外工具链。
xcodebuild 可以执行构建、测试、查询和 Archive;它本身不是“必须启动模拟器”的命令。是否依赖 Runtime,主要由 action 和 destination 决定。[Apple:Xcode 命令行工具参考](https://developer.apple.com/documentation/xcode/xcode-command-line-tool-reference?changes=la)

例如,面向真实设备的 Archive 可以使用类似下面的结构。示例中的项目、Scheme 和路径均为脱敏占位符:

xcodebuild \
  -workspace "AppWorkspace.xcworkspace" \
  -scheme "ReleaseScheme" \
  -configuration Release \
  -destination "generic/platform=iOS" \
  -archivePath "$PWD/build/App.xcarchive" \
  archive

关键不在命令长短,而在 destination 和 Scheme。若你的脚本隐藏地写入了 platform=iOS Simulator,或者先执行了模拟器专用生成步骤,那么“没有 Runtime 也能 Archive”的判断就不成立。

TestFlight 不等于模拟器测试

只做 TestFlight 上传时,通常流程是:

  1. 编译 Release 配置;
  2. 创建面向真实设备的 Archive;
  3. 执行代码签名;
  4. 对 Archive 做 Validate App;
  5. 上传到 App Store Connect;
  6. 等待后台处理并检查构建状态。
Apple 的发布文档明确把 Archive、Validate App 和上传 App Store Connect 放在发布流程中;这些动作本身不要求你先启动 iOS Simulator。[Apple:分发用于 Beta 测试和发布的 App](https://developer.apple.com/documentation/xcode/distributing-your-app-for-beta-testing-and-releases?changes=_7)

但不要把“只做 TestFlight”理解成“可以删除所有与设备相关的内容”。如果项目包含自定义脚本、截图生成、UI 自动化、模拟器启动检查,或者上传前脚本通过 simctl 生成测试数据,就必须把这些调用列入依赖清单。

发布机验收清单

  • [ ] 用当前提交执行一次干净的 Release Archive;
  • [ ] 确认 Archive 的 destination 面向真实设备,而不是 Simulator;
  • [ ] 检查 .xcarchive 是否生成且包含预期 App;
  • [ ] 检查签名身份、Entitlements 和 Provisioning Profile;
  • [ ] 执行 Validate App,并保存输出;
  • [ ] 执行上传流程,确认 App Store Connect 接收到构建;
  • [ ] 搜索脚本中的 simctlSimulatorxcrun 和模拟器 destination;
  • [ ] 冷启动远程 Mac 后重新执行一次 xcodebuild
  • [ ] 记录缺少组件时的恢复命令和安装路径。
Apple 说明 Archive 是包含调试信息的构建包,之后可以从 Archives Organizer 中执行验证、导出或上传。因此,命令返回 0 只能说明命令阶段结束,不能单独证明 Archive 内容、签名和上传链路都正确。

UIKit 开发者:验证 Interface Builder toolchain

Storyboard 和 XIB 的新边界

Xcode 27 Beta Release Notes 已确认,UIKit 文档新增 toolchain 编译模式,并默认启用。Apple 给出的目的就是允许 Interface Builder 文档在不下载模拟器的情况下编译,这对构建服务器尤其有用。

因此,含 Storyboard 或 XIB 的 UIKit 工程,是否依赖 Simulator Runtime,不能再只根据界面资源数量判断。如果只是使用默认的 Interface Builder toolchain 编译界面资源,通常不需要因为存在 Storyboard 或 XIB 而安装 Runtime。

Apple 同时提供了回退路径:如果项目在过渡阶段遇到问题,可以使用 IBC_COCOATOUCH_COMPILER_MODE = simulator,或在手动调用 ibtool 时指定 simulator 模式。此时,Runtime 就应被视为明确依赖,而不是可有可无的组件。Apple:Xcode 27 Beta Release Notes

项目设置与脚本检查

先检查工程和脚本中是否出现以下设置:

IBC_COCOATOUCH_COMPILER_MODE
simulator
ibtool
xcrun simctl

Apple 的 Build Settings Reference 对 IBC_COCOATOUCH_COMPILER_MODE 有单独说明;Storyboard 相关设置还包括 IBSC_COCOATOUCH_COMPILER_MODE。两者不要混为同一个变量,也不要为了“保险”把所有打包机统一改成 simulator 模式。Apple:Build Settings Reference

你可以用下面的方式查看实际生效的构建设置:

xcodebuild \
  -workspace "AppWorkspace.xcworkspace" \
  -scheme "ReleaseScheme" \
  -showBuildSettings \
  | grep -E "IBC_COCOATOUCH_COMPILER_MODE|IBSC_COCOATOUCH_COMPILER_MODE|SDKROOT|EFFECTIVE_PLATFORM_NAME"

然后使用包含真实 Storyboard、XIB、IBOutlet 和模块引用的提交执行 Archive。不要只拿空项目验证,因为空项目无法覆盖自定义字体、模块名、资源编译、约束冲突和脚本注入等边界。

⚠️ 注意:Xcode 27 的 Interface Builder toolchain 是 Beta 阶段能力。若 Archive 在 toolchain 模式下失败,先保存完整的 ibtoolxcodebuild 日志,再决定是否临时安装 Runtime 或回退模式;不要直接把所有发布机改成 simulator 依赖。

组件方案评分

<
环境方案Archive 适配度UI 测试适配度维护复杂度适合对象
精简发布机,不装 Runtime5 / 51 / 55 / 5只做 Archive、签名、上传
发布机同时安装少量 Runtime4 / 53 / 53 / 5偶尔需要模拟器验证的小团队
发布机与测试机分离5 / 55 / 54 / 5有稳定发布和持续测试需求的团队
所有 Runtime 全部安装2 / 55 / 51 / 5需要广泛兼容测试但缺少拆分条件的团队
评分不是性能测试,而是对组件职责、回滚风险和维护边界的工程判断。Apple 的组件管理机制支持按平台和版本安装、删除 Runtime,因此你可以根据测试计划逐步增加组件,而不是在初始化时一次性下载所有版本。

自动化测试者:按测试目标安装 Runtime

纯单元测试与 iOS Simulator 测试

“单元测试”不是一个足够精确的组件判断。你需要看测试目标最终运行在哪里:

  • 纯 macOS 逻辑测试:不按 iOS Simulator 配置;
  • 使用 iOS SDK 编译但不运行测试:先确认后续是否有执行阶段;
  • 面向 iOS Simulator 的单元测试:需要匹配 Runtime;
  • XCTest UI Tests:需要启动被测 App 和模拟设备;
  • build-for-testing:主要生成测试产物;
  • test-without-building:会实际执行已经生成的测试产物,因此需要可用 destination。
在自动化流水线中,build-for-testingtest-without-building 应视为两个阶段。前者主要负责生成测试产物,后者才会按照指定 destination 启动并执行测试。不要因为第一阶段成功,就宣称测试环境已经具备完整 Runtime。

典型命令可以拆成:

xcodebuild \
  -workspace "AppWorkspace.xcworkspace" \
  -scheme "TestScheme" \
  -destination "platform=iOS Simulator,name=脱敏设备,OS=脱敏版本" \
  build-for-testing

随后:

xcodebuild \
  -workspace "AppWorkspace.xcworkspace" \
  -scheme "TestScheme" \
  -destination "platform=iOS Simulator,name=脱敏设备,OS=脱敏版本" \
  test-without-building \
  -resultBundlePath "$PWD/results/AppTests.xcresult"

如果你的 Test Plan 中包含多个 iOS Simulator destination,就必须为每个目标建立 Runtime 和设备清单。Apple 的测试文档说明,Xcode 会根据 Scheme 和可用平台列出运行目标;没有对应平台支持或模拟环境时,不能按该目标运行应用。Apple:在模拟设备或实体设备上运行 App

UI Tests 的证据要求

XCTest UI Tests 不是普通编译检查。它们会通过 XCUIAutomation 操作界面,验证用户是否能完成具体流程,因此必须实际启动被测 App 和运行环境。Apple:添加测试到 Xcode 项目

每次自动化测试至少保留:

  • .xcresult 结果包;
  • 测试目标和 destination;
  • 测试计划版本;
  • 失败时的日志、截图或附件;
  • Runtime 与模拟设备标识;
  • 测试前后的应用版本和构建号。
Apple 说明,使用 xcodebuild 在终端运行测试时,会生成包含会话结果、代码覆盖率和日志的 Xcode Test Results 结果包。这个结果包比一行“命令成功”更适合作为流水线证据。[Apple:运行测试并解释结果](https://developer.apple.com/documentation/xcode/running-tests-and-interpreting-results?changes=_9)

SwiftUI 与兼容性团队:保留独立测试环境

SwiftUI Preview、交互调试、多设备布局检查和不同 iOS 版本回归,依赖的是可运行的模拟环境,不是单纯的 Interface Builder 编译。

如果你把精简发布机当成日常开发工作站,常见问题会变成:

  1. Preview 因缺少 Runtime 无法启动;
  2. 临近发布时临时下载 Runtime,改变了机器状态;
  3. 测试设备、Runtime 和 Xcode 版本不匹配;
  4. 发布机被临时测试任务占用,影响稳定 Archive;
  5. 测试失败后无法区分代码问题与环境缺失。
Apple 的文档明确指出,Simulator 用于在不同硬件和系统组合上调试,但它不能完全复制实体设备的性能和硬件特性;关键能力仍应在实体设备上验证。

因此,小团队更稳妥的分层方式是:

  • 发布环境:固定 Xcode、平台 SDK、签名材料和发布脚本,默认不安装无任务依赖的 Runtime;
  • 测试环境:按照 Test Plan 安装必要 Runtime,允许创建多个模拟设备;
  • 开发环境:服务于 Preview、交互调试、资源编辑和临时回归,不与正式发布机共用状态。
多版本兼容测试也应根据真实支持范围建立清单。Apple 提供了在多个 Simulator 平台和版本中安装应用的流程,但这类任务的核心是验证不同目标环境,不应反向成为所有发布机的默认组件。[Apple:在多个 Simulator 平台和版本中安装 App](https://developer.apple.com/documentation/xcode/installing-your-app-in-many-simulator-platforms-and-versions?changes=__7)

按真实流水线完成最终验收

五步组件核对法

第 1 步:列出实际 action。 从 CI 配置、Shell 脚本、Fastlane 配置和 Scheme 中提取 buildarchivetestbuild-for-testingtest-without-buildingsimctlibtool 调用。

第 2 步:列出 destination。 区分 generic/platform=iOS、实体设备 destination 和 platform=iOS Simulator。只有后者直接把 iOS Simulator Runtime 纳入任务依赖。

第 3 步:列出组件。 分别记录 Xcode、平台 SDK、Simulator Runtime、模拟设备、Metal Toolchain、证书和 Provisioning Profile,不要把它们合并成“Xcode 环境”。

第 4 步:执行冷启动验证。 重启远程 Mac,重新选择目标 Xcode,执行一次完整的 xcodebuild。这一步可以暴露只在交互式 Xcode 会话中存在的路径、权限和缓存问题。

第 5 步:保存交付证据。 发布任务保存 .xcarchive、签名检查、Validate App 和上传记录;测试任务保存 .xcresult、destination、Runtime 版本和失败附件。

如果你需要先准备一台远程 Mac 做验证,可以先查看 MACGPU 的远程 Mac 方案,按真实项目而不是空项目决定是否增加 Simulator Runtime。需要 Apple Silicon 环境时,也可以参考 M4 Mac 远程配置页面 了解可用的主机方案。

缺失组件时的恢复路径

不要把 Runtime 永久安装当作唯一恢复方案。Apple 支持通过 Xcode Components 管理界面,或使用命令行下载指定平台的模拟器组件;命令行方式可以先下载,再在多台 Mac 上导入。

例如,测试环境可以按需下载 iOS 平台组件:

xcodebuild \
  -downloadPlatform iOS \
  -exportPath "$PWD/Downloads"

安装前确认当前选择的 Xcode:

xcode-select -s "/Applications/Xcode-beta.app"
xcodebuild -runFirstLaunch

这里的重点不是背命令,而是把“发布机缺少 Runtime”与“测试机需要 Runtime”分成两个恢复路径。发布机不应因为一次临时 UI 测试就永久改变组件基线。

如果你当前使用的是 Beta,建议在 2026 年 9 月 5 日 之后每次更新 Xcode 27 Beta、RC 或正式版,都重新检查 Release Notes 中的 Interface Builder 条目和已知问题,并用同一脱敏项目执行最小 Archive 与模拟器测试对照。

FAQ:组件依赖的快速判断

不安装 iOS Runtime,Xcode 27 能否完成设备版 Archive?

可以,但前提是 Scheme 执行的是面向真实设备的 Build 或 Archive,而不是 iOS Simulator destination;同时项目使用的 iOS 平台 SDK、代码签名材料和发布配置必须齐全。建议用真实提交执行一次干净 Archive,再检查 xcarchive、签名结果和 Validate App 输出,不能只看 xcodebuild 返回成功。

UIKit 界面资源编译是否还会强制依赖模拟器?

在 Xcode 27 beta 的默认行为下,UIKit Storyboard 和 XIB 使用新的 Interface Builder toolchain 模式编译,不会仅因为存在界面资源就强制下载 Simulator Runtime。若项目或脚本显式设置 IBC_COCOATOUCH_COMPILER_MODE=simulator,或者需要运行界面测试和 Preview,则仍应安装匹配的 Runtime。

远程 iOS 打包机通常需要保留哪些 Xcode 组件?

最低配置应包括与项目匹配的 Xcode、目标平台 SDK、命令行工具、签名证书与 Provisioning Profile 所需的密钥材料,以及项目实际使用的额外工具链。Simulator Runtime、模拟设备和 Metal Toolchain 不应默认全部安装,应依据 Scheme、脚本、测试计划和 destination 逐项确认。

只做 TestFlight 发布时,哪些模拟器组件可以移除?

如果任务只执行 Release Archive、签名、Validate App 和上传 TestFlight,通常可以删除不使用的 iOS Simulator Runtime 与模拟设备。删除前要确认流水线没有调用 simctl、模拟器专用脚本、UI Tests、Preview 渲染或 simulator destination,并保留一次删除后的冷启动发布验收记录。

xcodebuild 哪些测试阶段必须具备模拟器环境?

使用 iOS Simulator destination 实际运行测试的 xcodebuild test,以及随后执行 test-without-building 的测试阶段,都需要匹配的 Simulator Runtime 和可用模拟设备。build-for-testing 主要生成测试产物,是否需要 Runtime 取决于后续执行阶段;纯 macOS 测试则不应按 iOS 模拟器规则配置。

当前环境与远程 Mac 方案的取舍

如果你现在把本地 Mac 同时当作开发机、测试机和发布机,隐性成本通常来自三处:Runtime 与缓存持续占用磁盘,临时测试会改变稳定发布环境,设备和证书问题也更难在远程流水线中复现。Windows 或 Linux 主机则无法直接提供完整的 Xcode、Interface Builder 和 xcodebuild 发布链路,长期依赖临时转发或不稳定的替代环境,维护边界会更模糊。

更合理的做法是先按任务申请一段短期远程 Mac 验证周期:纯发布任务从精简环境开始,需要 Simulator 或 UI Tests 时再增加测试环境;如果项目长期高频运行模拟器测试,则选择独立测试节点,而不是反复改造唯一的发布机。这样既不会为不会执行的 Runtime 长期预留资源,也能让 Archive、签名和上传保持可重复。