这是 React Native / Expo 项目的 iOS 模拟器构建技能,目标是在一条命令下完成经过验证的 Release 模拟器构建。
用途
将 Expo 应用构建为 Release 模拟器应用,并证明构建产物符合预期:使用固定版本的 Xcode、指定的变体(development / preview / production),应用能启动并在模拟器上正确绘制界面。主要用于 iOS 模拟器冒烟测试,以及验证变体、Metro、测试代码或构建工具链的变更。
主要能力
- 单一构建入口:所有模拟器构建通过
scripts/build/build-ios-sim.ts执行,先预检所有将运行的 npm 脚本,然后从干净的 prebuild 开始。 - Xcode 版本固定:通过
DEVELOPER_DIR按进程选择 Xcode 版本,不使用xcode-select或 sudo。scripts/ios/toolchain.ts固定XCODE_VERSION和IOS_RUNTIME。 - 变体环境一次导出:
variantEnv(variant)设置APP_VARIANT = EXPO_PUBLIC_APP_VARIANT,确保 prebuild、Constants 构建阶段和 Metro 使用同一环境。 - Metro 缓存键:
metro.config.js基于EXPO_PUBLIC_*值设置cacheVersion,避免在 CI=1 时 Release 打包跳过--reset-cache导致旧变体混入。 - 模拟器命名与 UDID 目标:模拟器按
<prefix>-<purpose>命名,创建一次并仅通过 UDID 操作;只关闭、擦除或删除自己前缀的模拟器。 - 等待就绪信号:通过契约中的 readyMarker 文件或两张间隔至少 3 秒的相同截图判断就绪,不使用固定 sleep。
- 截图检查:生成截图后需打开查看,确认显示预期屏幕、文字已绘制、无弹窗、无通知横幅、无空白区域。
- 产物证明:
check-sim-app.mjs读取 .app,验证 Xcode 版本、模拟器平台、测试专用哨兵、Info.plist 与 EXConstants 的 bundle id 一致性、多语言用途字符串、隐私清单、ATS 例外、占位符和加密标志等。 - 背靠背变体证明:当变更涉及变体、Metro、测试代码或构建工具时,连续执行 preview 和 production 构建(不清缓存),两者都通过检查。
使用方式
- 首次使用或安装检查失败时,阅读
references/environment-and-xcode.md和references/build-variants.md。 - 安装缺失的模板文件,填写契约中的
__SIMULATOR_PREFIX__和__APP_ID__。 - 在
package.json添加"build:ios:sim": "node scripts/build/build-ios-sim.ts",检查.gitignore规则,运行类型检查、ESLint 和 Jest。 - 运行
node ${CLAUDE_SKILL_DIR}/scripts/check-sim-setup.mjs .检查设置,修复所有 FAIL 直到 RESULT: PASS。 - 构建并运行:
npm run build:ios:sim -- --variant preview,可选--sim <purpose>选择其他模拟器,或--link <path> --wait-for <testID>通过 Maestro 子流程截图深链页面。运行会打印 .app 路径和截图路径。 - 证明构建:
node ${CLAUDE_SKILL_DIR}/scripts/check-sim-app.mjs . --app <app路径> --variant preview,然后node ${CLAUDE_SKILL_DIR}/scripts/check-screenshot.mjs reports/ios-sim/,打开 PNG 查看。 - 若变更涉及变体、Metro、测试代码或工具链,紧接着运行
--variant production构建(不清缓存),两者都运行 check-sim-app。 - 任何失败参考
references/failures.md,修复原因后重跑失败步骤和检查。需要密码的操作停下来询问开发者。 - 结束时按 UDID 关闭本次会话的模拟器。
适用场景
- 在 iOS 模拟器上进行冒烟测试。
- 验证变体、Metro 缓存、测试代码隔离或构建工具链变更。
- 需要可复现、可证明的 Release 模拟器构建产物。
限制
- 安装 Xcode、接受许可和首次启动设置需要 sudo 和管理员密码,必须由开发者完成,技能不会绕过。
- 构建是 Release 模拟器构建,不涉及签名。
- 需要仓库中已配置好相关模板和契约文件。
- 仅在文档记录的环境中验证过(Expo SDK 57、React Native 0.86.3、Xcode 26.6、iOS 26.5 模拟器运行时)。