使用AI代理构建iOS应用:实践者指南
# 借助AI代理更快构建iOS应用。涵盖Claude Code、Codex CLI、Xcode 26.3原生支持、MCP、CLAUDE.md模式、钩子,以及来自8款应用的实践经验。
TL;DR: 现在有3种智能体运行时可以为iOS交付代码:带有MCP的Claude Code CLI、带有MCP的Codex CLI,以及Xcode 26.3原生的Intelligence智能体。两个MCP服务器(拥有59个工具的XcodeBuildMCP,以及拥有20个工具的Apple
xcrun mcpbridge)让智能体能够以结构化方式访问构建、测试、模拟器和调试。本指南涵盖真实的CLAUDE.md模式、hook配置,以及对哪些可行、哪些会出问题的坦诚评估——这些经验来自8个生产级iOS应用,共计293个Swift文件。18智能体擅长SwiftUI视图、SwiftData模型、重构和构建错误诊断。它们不擅长.pbxproj修改、代码签名和视觉调试。“智能体会写Swift”和“智能体能交付iOS应用”之间的差距,靠配置弥合,而不是靠提示词。
我已经用AI编码智能体构建了8个iOS应用。不是原型,而是上架App Store的应用,包含HealthKit集成、Metal着色器、SpriteKit物理、iCloud同步、Live Activities、Game Center排行榜,以及横跨iOS、watchOS和tvOS的多平台目标。这些应用中的每一行Swift,要么由智能体编写并由我审查,要么由我编写并由智能体重构。按我的估算,行级作者身份的大部分由智能体完成;我负责审查、范围控制,以及需要人类判断的部分(视觉打磨、签名、性能调优、App Store提交)。
这就是我刚开始时希望能看到的参考资料。它覆盖完整技术栈:该使用哪种智能体运行时,如何配置MCP服务器来获得结构化构建访问,把什么写进CLAUDE.md,哪些hook可以防止智能体毁掉您的Xcode项目,以及最关键的一点:智能体会在哪里失败,您需要亲自接管。
关键要点
面向刚接触AI智能体的iOS开发者:
- 从Claude Code CLI + XcodeBuildMCP开始。 这是最成熟的运行时,拥有最深入的MCP工具覆盖。安装两条命令,向项目添加CLAUDE.md,智能体就能在无需您复制错误信息的情况下构建、测试和调试。
- 绝不要让智能体修改.pbxproj。 这是唯一最重要的规则。一个阻止写入
.pbxproj和.xcodeproj/的PreToolUse hook,可以为您省下数小时恢复时间。 - 您的CLAUDE.md就是智能体的入门文档。 花在它上面的时间,会在之后每一次触碰该项目的智能体会话中持续回报。
面向希望把iOS加入工作流的资深智能体用户:
- MCP会改变iOS构建循环。 在MCP之前,智能体能写Swift,却无法验证它是否能编译。有了XcodeBuildMCP,智能体可以编写代码、构建代码、读取结构化错误、修复错误并运行测试——全程自主完成。
- 三种运行时服务于不同需求。 Claude Code CLI适合深度智能体会话,Codex CLI适合无头批处理工作,Xcode 26.3原生智能体适合不离开IDE的快速内联修复。
- hook基础设施可以沿用。 现有的PostToolUse格式化器、PreToolUse阻断器和测试运行器hook,只需少量路径调整,就能同样用于iOS项目。
面向评估AI辅助iOS开发的团队负责人:
- 智能体效果随项目文档质量扩展,而不是随项目大小扩展。 一个拥有详细CLAUDE.md的63文件应用,比一个没有文档的14文件应用能产出更好的智能体结果。
- .pbxproj边界不可协商。 智能体无法可靠编辑Xcode项目文件。您的工作流必须考虑手动将文件添加到Xcode目标。
- 坦诚的ROI:在文档完善的项目中,智能体能承担实现工作的主体——下面的案例研究中,15文件TV应用在3小时智能体辅助工作内完成交付,这一点清晰可见。剩余工作——视觉打磨、签名、性能调优、App Store提交——仍然需要人类判断。
选择您的路径
| 您需要什么 | 前往这里 |
|---|---|
| 首次设置MCP | MCP设置:完整配置——安装两个服务器、验证、配置智能体 |
| 为iOS项目编写CLAUDE.md | iOS项目的CLAUDE.md模式——来自8个应用的真实示例 |
| 比较三种智能体运行时 | 面向iOS的三种智能体运行时——Claude Code vs. Codex vs. Xcode原生 |
| 了解智能体能做什么、不能做什么 | 智能体擅长什么和智能体不擅长什么 |
| 为iOS开发设置hook | iOS开发hook——保存时格式化、.pbxproj保护、测试运行器 |
| 深度参考(本页) | 继续阅读——从设置到高级模式一应俱全 |
如何使用本指南
这是一份超过3,000行的参考资料。请根据您的经验水平从合适的位置开始:
| 经验 | 从这里开始 | 然后探索 |
|---|---|---|
| 刚接触iOS + 智能体 | 前置条件 → MCP设置 → 您的第一次智能体会话 | CLAUDE.md模式、哪些可行/不可行 |
| iOS开发者,刚接触智能体 | 三种运行时 → MCP设置 → CLAUDE.md | Hooks、架构模式 |
| 智能体用户,刚接触iOS | 架构模式 → 智能体不擅长什么 → CLAUDE.md | 框架特定上下文、高级工作流 |
| 两者都有经验 | 高级工作流 → Hooks → 多平台模式 | 运行时对比、作品集 |
目录
- 作品集:8个应用,293个文件
- 前置条件
- 面向iOS的三种智能体运行时
- MCP设置:完整配置
- iOS项目的CLAUDE.md模式
- 您的第一次智能体会话
- 智能体在iOS中擅长什么
- 智能体在iOS中不擅长什么
- iOS开发hook
- 适合智能体协作的架构模式
- 框架特定上下文
- 多平台模式
- 高级工作流
- 真实案例研究
- 使用智能体的项目生命周期
- 配置智能体定义
- 智能体辅助iOS的测试模式
- iOS项目的上下文窗口管理
- 故障排查
- iOS中常见的智能体错误
- 坦诚评估
- FAQ
- 快速参考卡
- 参考资料
相关资源
| 主题 | 资源 |
|---|---|
| 面向Xcode的MCP设置(较短博客文章) | 两个MCP服务器让Claude Code成为iOS构建系统 |
| Claude Code CLI完整参考 | Claude Code CLI:完整指南 |
| Codex CLI参考 | Codex CLI:完整指南 |
| hook系统深度解析 | 爪子的解剖:作为编排层的84个hook |
| 智能体架构模式 | 智能体架构指南 |
| Mac桌面应用 + Remote Control | Claude Code Mac Desktop + Remote Control:CLI用户指南 |
Apple生态系统系列。 21篇生产级文章,介绍集成Apple Intelligence、MCP、Foundation Models、Vision、Core ML和iOS 26框架栈的SwiftUI应用。内容来自Water、Get Bananas、Return以及941作品集的其他项目:
系列中心: Apple生态系统系列
智能体式Apple(E4):
| 主题 | 资源 |
|---|---|
| Apple Intelligence的intent界面 | App Intents是Apple通向您应用的新API |
| 与iOS应用并行存在的MCP服务器 | 两个智能体生态系统,一份购物清单 |
| 何时使用哪一个 | App Intents vs MCP Tools:路由问题 |
| 作为运行时功能与工具链的端侧LLM | Foundation Models + 智能体式工作流 |
| Apple开发hook | Apple开发hook |
| 跨进程状态 | 单一事实来源:SwiftData + MCP + iCloud |
框架(E2/E3):
| 主题 | 资源 |
|---|---|
| Foundation Models端侧LLM | Foundation Models端侧LLM |
| Vision框架(CV原语) | Vision框架:内置了什么 |
| Core ML推理模式 | Core ML端侧推理 |
| RealityKit空间心智模型 | RealityKit与空间心智模型 |
| SwiftUI内部机制 | SwiftUI由什么构成 |
| Symbol Effects动画词汇 | Symbol Effects:SwiftUI内置动画词汇 |
| iOS 26+上的Liquid Glass | SwiftUI中的Liquid Glass:三种模式 |
已交付代码(E1):
| 主题 | 资源 |
|---|---|
| Live Activities状态机 | Live Activities状态机 |
| watchOS运行时契约 | watchOS运行时契约 |
| SwiftData schema纪律 | SwiftData Schema纪律 |
| HealthKit + SwiftUI模式 | iOS 26上的HealthKit + SwiftUI |
| 多平台SwiftUI | 五个Apple平台,三个共享文件 |
| XcodeBuildMCP集成 | 两个MCP服务器,一个Xcode项目 |
综合(E5):
| 主题 | 资源 |
|---|---|
| iOS应用的三个界面 | iOS应用的三个界面 |
| 平台目标决策 | Apple平台矩阵 |
| 我拒绝写什么 | 我拒绝写什么 |
作品集:8个 App,293个文件
在深入配置之前,先说明本指南的经验来源。这些并非玩具项目,而是覆盖5个 Apple 框架、3个平台,以及从14个文件的健身记录器到63个文件的多平台冥想计时器的完整 iOS 复杂度范围。
| App | 技术栈 | 文件数 | 复杂度 |
|---|---|---|---|
| Banana List | SwiftUI + SwiftData + iCloud Drive 同步 + 用于 Claude Desktop 的 MCP 服务器 | 53 | 完整 CRUD、iCloud 同步、自定义 MCP 服务器,将 App 数据暴露给 Claude Desktop |
| Ace Citizenship | SwiftUI 学习 App + FastAPI 后端 | 26 | 客户端-服务器、REST API 集成、测验引擎 |
| TappyColor | SpriteKit 颜色匹配游戏 | 30 | 游戏循环、物理、触摸处理、粒子效果 |
| Return | 禅修冥想计时器 — iOS 26+、watchOS、tvOS | 63 | HealthKit、Live Activities、Watch 扩展运行时、TV 焦点导航、iCloud 会话同步 |
| amp97 | Metal 着色器 + 音频可视化 | 41 | 自定义 Metal 渲染管线、音频分析、实时 GPU 计算 |
| Reps | SwiftUI + SwiftData 健身记录 | 14 | 最小可行 App、清晰的 SwiftData 模式 |
| Water | SwiftUI + SwiftData + Metal + HealthKit 饮水记录 | 34 | Metal 流体模拟、HealthKit 饮水量记录、widget |
| Starfield Destroyer | SpriteKit + Metal 太空射击游戏 | 32 | 99个关卡、8艘飞船、Game Center 排行榜、Metal 后处理 |
为什么文件数量重要:Agent 的有效性与项目可读性相关,而不是与项目规模相关。Return(63个文件)比 amp97(41个文件)能产生更好的 agent 输出,因为 Return 有一份详细的 CLAUDE.md,其中包含文件注释、架构图和明确模式。无论文档质量如何,amp97 的 Metal 着色器本身都更难让 agent 推理。
前提条件
在为 iOS 开发设置任何 agent 运行时之前:
App Store Connect 截止日期:从 2026-04-28 开始,上传到 App Store Connect 的 App 必须使用 Xcode 26 或更高版本构建,并使用适用于 iOS 26、iPadOS 26、tvOS 26、visionOS 26 或 watchOS 26 的 SDK。12(macOS 提交不受此要求限制。)如果团队仍在使用 Xcode 16.x,本指南中的 agent 辅助工具链也会成为一种倒逼机制——反正下面这些 MCP 服务器都离不开 Xcode 26.3+。
必需:
- macOS 15+(Sequoia)或 macOS Tahoe
- 已安装并配置 Xcode 26.3+(xcrun mcpbridge 的最低要求);建议使用 Xcode 26.5+,以获得 agent 工作流升级——编码助手中的消息队列和澄清问题支持——以及 Swift Testing 图像附件、记录问题严重级别、带 crashlog 的 UI 测试崩溃警告,以及最早在 26.4 中加入的 String Catalog 编辑器改进。1314 Xcode 26.5(2026年5月11日,build 17F42)是最新稳定版;26.4.1(2026年4月16日,build 17E202)是 26.4 系列最后一个错误修复版本。15
- 至少安装一个 iOS Simulator 运行时
- 一个 Anthropic API 账户(用于 Claude Code)或 OpenAI 账户(用于 Codex)
推荐:
- 安装 SwiftFormat(brew install swiftformat)——供保存时格式化 hooks 使用
- 安装 SwiftLint(brew install swiftlint)——可选,但对风格约束很有帮助
- 熟悉终端——3种运行时都从命令行运行,或与命令行集成
验证 Xcode 安装:
# Check Xcode version
xcodebuild -version
# Expected: Xcode 26.3 or later (26.5+ recommended)
# Check available simulators
xcrun simctl list devices available
# Expected: at least one iPhone simulator
# Verify xcrun mcpbridge is available
xcrun mcpbridge --help
# Expected: usage information (not "command not found")
如果 xcrun mcpbridge 返回“command not found”,则需要 Xcode 26.3 或更高版本。请通过 App Store 或 developer.apple.com 安装或更新 Xcode。注意:xcode-select --install 只会安装 Command Line Tools,其中不包含 mcpbridge——您需要完整的 Xcode.app。
iOS的三种Agent运行时
有三种不同的运行时可以编写、构建和测试iOS代码。它们并非可以互换——每种运行时都有不同的优势、不同的MCP集成模式以及不同的理想使用场景。
1. Claude Code CLI
它是什么: Anthropic推出的基于终端的agentic编码助手。可读取您的代码库、执行命令、修改文件,并通过MCP连接外部工具。
MCP集成: 完全支持XcodeBuildMCP和Apple的Xcode MCP。Agent通过MCP协议发现工具,并使用结构化参数调用它们。两个服务器共计59 + 20个工具。
安装配置:
# Install Claude Code (if not already installed)
claude --version # verify installation
# Add XcodeBuildMCP (59 tools — builds, tests, simulators, debugging)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Add Apple Xcode MCP (20 tools — file ops, diagnostics, Swift REPL, previews)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
替代方案 — xcodebuildmcp init 自动安装器(v2.1.0+,2026-02-23):
如果您想跳过手动MCP配置,XcodeBuildMCP v2.1.0+附带了init子命令,可自动检测Claude Code、Cursor或Codex,并一步完成agent skills + MCP配置的安装:
xcodebuildmcp init
# Or without a global install:
npx -y xcodebuildmcp@latest init
参数:--print(将配置写入stdout以适配不受支持的客户端)、--uninstall(卸载)。如果您希望明确控制接入哪些MCP服务器以及作用范围,请跳过此步骤;上面的手动claude mcp add调用方式可以提供这种控制。16
最适合: 深度实现会话——构建新功能、跨多文件重构、调试复杂问题、自主运行构建-测试-修复循环。Claude Code的1M上下文窗口(搭配Opus 4.6)意味着agent可以将大多数中小型iOS项目装入工作记忆——根据我的经验,大约可容纳50个文件,具体取决于文件大小。
典型会话:
You: Add a new SettingsView with toggles for notifications and haptic feedback.
Use the existing Settings.swift pattern from TimerManager.
Build for simulator after implementation and fix any errors.
Claude: [reads Settings.swift, TimerManager.swift, existing views]
[creates SettingsView.swift]
[calls build_sim via MCP]
[reads structured error: missing import HealthKit]
[fixes import]
[calls build_sim again — success, 0 errors, 1 warning]
[calls test_sim — all tests pass]
与MCP出现之前的工作流相比,关键区别在于:agent从不要求您手动构建或粘贴错误输出。构建-报错-修复的循环是自主完成的。
2. Codex CLI
它是什么: OpenAI推出的基于终端的编码agent。概念上与Claude Code类似,但使用OpenAI模型(GPT-4o、o3),并且具有不同的权限模型。
MCP集成: Codex通过codex mcp add命令支持MCP。Apple的Xcode MCP可直接使用:
# Add Apple Xcode MCP to Codex
codex mcp add xcode -- xcrun mcpbridge
XcodeBuildMCP也可通过相同的npx命令与Codex配合使用:
# Add XcodeBuildMCP to Codex
codex mcp add XcodeBuildMCP -- npx -y xcodebuildmcp@latest mcp
最适合: 无人值守的批处理操作、CI/CD集成,以及希望从不同模型家族获得第二意见的任务。Codex的沙箱模式在隔离环境中运行代码,这对于会修改状态的破坏性操作(如测试套件运行)非常有用。
与Claude Code的关键区别:
- 使用OpenAI模型而非Claude模型
- 不同的上下文窗口大小和token经济学
- 沙箱优先的权限模型(默认更严格)
- MCP生态系统较小(经过测试的社区服务器更少)
- 提供Hooks系统(v0.119.0+),但成熟度不及Claude Code——事件类型较少,且没有条件性if字段
在iOS开发中何时选择Codex而非Claude Code:
当您希望获得模型多样性时使用Codex——让第二个agent审查第一个agent编写的代码,可以发现不同类别的错误。collab工作流(Claude构建,Codex审查)对iOS非常有效,因为某个模型家族认为正确的SwiftUI模式可能存在另一个模型才能发现的细微问题。Metal着色器和并发模式尤其能从双模型审查中受益。
3. Xcode 26.3 原生Agent
它是什么: Apple将AI编码agent直接集成到了Xcode的Intelligence面板中。从Xcode 26.3开始,您可以在Xcode Settings > Intelligence中将Claude Agent和Codex配置为智能服务提供方。
安装配置:
- 打开Xcode 26.3+
- 导航至 Settings > Intelligence
- 添加新的提供方:
- 对于Claude:选择”Claude Agent”,输入您的Anthropic API密钥
- 对于Codex:选择”Codex”,输入您的OpenAI API密钥
- Agent会出现在Intelligence侧边栏中,可在行内调用
最适合: 快速行内编辑、具备agent级推理能力的代码补全,以及不愿离开Xcode的开发者。原生集成意味着agent可直接访问Xcode的项目上下文——已打开的文件、构建目标、scheme配置——无需MCP桥接。
与CLI agent相比的局限: - 无Hook系统——无法强制保存时格式化或阻止对.pbxproj的写入 - 不加载CLAUDE.md——agent不会读取您的项目级配置文件 - 自主性有限——agent仅作用于当前文件或选区,而非整个项目 - 无subagent委派——复杂的多步任务无法并行化 - 无MCP服务器配置——agent仅使用Xcode内置工具
何时使用Xcode原生Agent:
适用于切换到终端代价过高的快速、局部编辑。”为这个model添加一个计算属性。”“为这个function编写一个单元测试。”“将这个view重构为使用@Observable。”——只涉及一两个文件且无需构建-测试循环的任务。
任何需要构建、测试、多文件重构或自主纠错的工作,请使用搭配MCP的CLI agent。
运行时对比矩阵
| 能力 | Claude Code CLI | Codex CLI | Xcode 26.3 原生 |
|---|---|---|---|
| MCP支持 | 完整(79个工具) | 完整(79个工具) | 仅Xcode内置工具 |
| Hook系统 | 是(成熟) | 是(基础,v0.119.0+) | 无 |
| CLAUDE.md / 项目配置 | 是 | codex.md等价物 | 无 |
| 自主构建-测试-修复 | 是(通过MCP) | 是(通过MCP) | 部分(仅行内) |
| Subagent委派 | 是(最多10个并行) | 否 | 否 |
| 上下文窗口 | 1M tokens(Opus 4.6) | 因模型而异 | 因提供方而异 |
| 多文件操作 | 完整代码库访问 | 完整代码库访问 | 当前文件 / 选区 |
| .pbxproj保护 | 通过hooks | 手动 | 不适用(原生使用Xcode) |
| 保存时格式化 | 通过PostToolUse hooks | 外部工具链 | Xcode设置 |
| 离线能力 | 无 | 无 | 无 |
| 计费模式 | Anthropic API使用量 | OpenAI API使用量 | 提供方API使用量 |
建议: 将Claude Code CLI作为主要运行时。使用Xcode 26.3原生agent进行快速行内编辑。使用Codex CLI进行审查和批处理操作。三者相辅相成,而非相互竞争。
MCP设置:完整配置
MCP(Model Context Protocol)能让代理从“编写Swift,然后希望您自己构建”转变为“编写Swift、执行构建、读取结构化错误并修复问题”。本节比博客文章更深入,涵盖两个服务器、所有安装方式、验证步骤,以及确保工具被真正使用的代理配置。
XcodeBuildMCP:用于无头iOS开发的59个工具
XcodeBuildMCP将xcodebuild、xcrun simctl和LLDB封装为59个结构化MCP工具。它无需运行Xcode即可工作,整个构建、测试、调试循环都通过Apple的命令行工具以无头方式运行。
安装选项:
# Option 1: Via npx (recommended — always uses latest version)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Option 2: Via Homebrew (pinned version, manual updates)
brew install xcodebuildmcp
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- xcodebuildmcp mcp
# Option 3: Project-scoped (omit -s user)
claude mcp add XcodeBuildMCP \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
-s user标志会让该服务器在所有项目中全局可用。如果需要项目级安装,可以省略它(如果您只想在iOS项目中使用MCP,而不想在Web项目中使用,这会很有用)。
-e XCODEBUILDMCP_SENTRY_DISABLED=true环境变量会禁用崩溃报告遥测。XcodeBuildMCP默认包含Sentry,会发送包含文件路径在内的错误数据。除非您希望为该项目贡献诊断信息,否则建议选择退出。1
完整工具清单(8个类别,共59个工具):
| 类别 | 工具 | 作用 |
|---|---|---|
| 项目发现 | discover_projs、list_schemes、list_targets |
查找.xcodeproj/.xcworkspace文件,列出可用scheme和target |
| 构建 | build_sim、build_device、build_mac |
按文件和行号输出结构化JSON错误/警告信息并执行构建 |
| 测试 | test_sim、test_device |
运行测试,并返回每个测试方法的通过/失败结果 |
| 模拟器生命周期 | list_sims、boot_sim、shutdown_sim、open_sim、session_set_defaults |
创建、启动、管理和配置模拟器 |
| 设备管理 | list_devices、install_device、launch_device |
真实设备部署与管理 |
| 调试 | debug_attach_sim、debug_attach_device、debug_breakpoint、debug_stack、debug_variables、debug_eval、debug_continue、debug_step、debug_detach |
完整LLDB集成,支持断点和变量检查 |
| UI自动化 | snapshot_ui、screenshot、tap、swipe、type_text |
自动交互与视觉捕获 |
| 项目脚手架 | create_project、add_file、add_package |
创建项目并添加依赖 |
日常工作中最重要的工具:
-
build_sim——您会调用它数百次。它返回JSON,并按文件、行号和严重级别对错误分类。代理会读取错误、跳转到对应文件并完成修复,无需您动手。 -
test_sim——返回每个测试方法的结果。代理能准确知道哪个测试失败以及失败原因,而不只是看到“测试失败”。 -
list_sims+boot_sim——无需记忆xcrun simctl标志即可管理模拟器。代理会发现可用运行时,并选择合适的设备。 -
discover_projs+list_schemes——项目内省。代理不需要猜测您的scheme名称或workspace结构。 -
debug_attach_sim+debug_stack+debug_variables——远程LLDB调试。代理可以设置断点、检查变量并逐步执行代码,而无需您打开调试器。
Apple Xcode MCP:桥接到Xcode的20个工具
Apple的MCP服务器随Xcode 26.3通过xcrun mcpbridge提供。它通过XPC(Apple的进程间通信框架)与正在运行的Xcode进程通信,暴露任何CLI工具都无法访问的内部状态。
安装:
# Standard installation (global)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
# For Codex CLI
codex mcp add xcode -- xcrun mcpbridge
需要Xcode 26.3+以及正在运行的Xcode进程。如果Xcode未打开,通过此服务器发起的每个MCP调用都会失败或挂起。XcodeBuildMCP没有这个限制。
工具清单(5个类别,共20个工具):
| 类别 | 工具 | 作用 |
|---|---|---|
| 文件操作 | XcodeRead、XcodeWrite、XcodeUpdate、XcodeGlob、XcodeGrep |
在Xcode项目上下文中读取/写入文件 |
| 构建与测试 | BuildProject、GetBuildLog、RunAllTests、RunSomeTests |
使用Xcode内部构建系统进行构建和测试 |
| 诊断 | XcodeListNavigatorIssues、XcodeRefreshCodeIssuesInFile |
实时代码诊断(不只是构建错误) |
| 代码与文档 | ExecuteSnippet、DocumentationSearch |
Swift REPL执行和Apple文档搜索 |
| 预览 | RenderPreview |
无头SwiftUI预览渲染 |
Apple MCP独有的工具(XcodeBuildMCP中不可用):
-
DocumentationSearch——搜索Apple开发者文档,包括WWDC会议内容。对于Apple API问题,它比Web搜索更快、更可靠。询问“is HKQuantityType(.dietaryWater) valid?”即可从来源获得明确答案。 -
ExecuteSnippet——在项目上下文中执行Swift REPL。代理可以验证API行为、测试类型转换,并在不构建完整应用的情况下验证表达式。 -
RenderPreview——以无头方式渲染SwiftUI预览。代理可以检查某个视图是否能无错误渲染,但无法评估视觉正确性(渲染结果作为数据返回,而不是经过视觉检查)。 -
XcodeListNavigatorIssues——返回Xcode分析器的实时诊断,而不只是构建错误。它能捕获未使用变量、潜在保留环、弃用警告等构建系统不会暴露的问题。
为什么需要两个服务器
它们在构建和测试方面有所重叠,但本质上不同:
┌─────────────────────────────────────────────────────────────────┐
│ MCP TOOL COVERAGE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ XcodeBuildMCP (59 tools) Apple Xcode MCP (20 tools) │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Standalone │ │ Requires Xcode │ │
│ │ (no Xcode process) │ │ (XPC bridge) │ │
│ │ │ │ │ │
│ │ ✓ Simulators │ BOTH │ ✓ Documentation │ │
│ │ ✓ Real devices │ ┌─────┐ │ ✓ Swift REPL │ │
│ │ ✓ LLDB debugging │ │Build│ │ ✓ SwiftUI previews │ │
│ │ ✓ UI automation │ │Test │ │ ✓ Live diagnostics │ │
│ │ ✓ Project scaffold │ └─────┘ │ ✓ Analyzer issues │ │
│ │ ✓ Screenshot │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
将XcodeBuildMCP用于:构建、测试、调试循环。它无需打开Xcode,占用更少系统内存,并提供更丰富的模拟器和设备管理能力。这是您的主要构建工具。
将Apple Xcode MCP用于:文档查询、Swift REPL验证、SwiftUI预览渲染和实时诊断。在需要这些能力的会话中,请保持Xcode打开。
实际使用中:我大约90%的MCP调用使用XcodeBuildMCP,Apple Xcode MCP则用于文档和REPL验证。代理默认用XcodeBuildMCP进行构建和测试,因为它更快(没有Xcode进程开销),也更可靠(不依赖XPC)。
验证
安装两个服务器后,验证它们是否已连接:
# List all configured MCP servers
claude mcp list
# Expected output includes:
# XcodeBuildMCP: npx -y xcodebuildmcp@latest mcp - Connected
# xcode: xcrun mcpbridge - Connected
如果某个服务器显示“Disconnected”或没有出现:
- XcodeBuildMCP无法连接:确保已安装Node.js(
node --version)。npx命令需要Node.js 18+。 - Apple Xcode MCP无法连接:确保已安装Xcode 26.3+,并且
xcrun mcpbridge命令可在终端中运行。至少打开一次Xcode以接受许可协议。 - 两个都未出现:重启Claude Code(在新终端中运行
claude)。会话中途注册的MCP服务器可能要等到重启后才会出现。
教会代理使用MCP
安装MCP服务器是必要条件,但还不够。如果没有明确指引,代理可能会退回到通过Bash运行xcodebuild(输出非结构化,浪费上下文token),或使用Web搜索查询Apple文档(更慢,也不够可靠)。
将以下内容添加到您的CLAUDE.md或代理定义中:
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim` (NOT `xcrun simctl` via Bash)
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
- **Previews**: `RenderPreview` for headless SwiftUI verification
MCP returns structured JSON. Bash returns unstructured text.
Structured data means fewer tokens consumed and better error diagnosis.
这段指引能确保代理优先使用MCP工具。否则,您会看到代理通过Bash构造很长的xcodebuild命令,消耗数千个上下文token来解析输出,有时还会误判真正的错误。
iOS项目的CLAUDE.md模式
在智能体辅助开发中,CLAUDE.md是项目里最重要的文件。它是智能体的入职文档——决定了它像读过架构文档的新员工,还是只能靠猜的新员工。
我维护的每个iOS项目都有CLAUDE.md。下面这些模式来自全部8个应用,实践证明有效。
核心章节
每个iOS CLAUDE.md都需要这6个章节。其他内容都是可选的。
1. 项目身份信息
# Return - Zen Focus Timer
**Bundle ID:** `com.941apps.Return`
**Target:** iOS 26+ / macOS Tahoe / watchOS 26+ / tvOS 26+
**Architecture:** SwiftUI with @Observable pattern, companion Watch and TV apps
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
为什么重要:智能体在编写任何代码之前,都需要知道部署目标。面向iOS 17的智能体会使用NavigationView和@ObservedObject。面向iOS 26的智能体会使用NavigationStack和@Observable。Bundle ID会影响entitlements和HealthKit配置。Swift版本决定并发模型(async/await还是完成回调,严格并发还是宽松并发)。
2. 带用途标注的文件结构
## File Structure
```
Return/
├── ReturnApp.swift # App entry, dark mode enforcement
├── ContentView.swift # Main timer view with theme backgrounds
├── TimerManager.swift # Timer state, logic, and repeat handling
├── AudioManager.swift # Sound playback with AVAudioPlayer
├── Settings.swift # Centralized settings with validation
├── SettingsSheet.swift # Settings UI
├── HealthKitManager.swift # Mindful session logging + cross-device sync
├── LiveActivityManager.swift # Lock Screen/Dynamic Island
├── Theme.swift # Theme definitions
├── ThemeManager.swift # Theme state management
├── VideoBackgroundView.swift # AVPlayer video backgrounds
├── GlassTextShape.swift # Core Text glyph paths for glass effect
├── GlassTimerText.swift # Timer text with glass material
└── Constants.swift # App constants
```
每个文件名后的内联注释不是装饰。它们是您能写下的最具杠杆效应的文档。当智能体决定在哪里添加新功能时,这些标注会让它第一次就找到正确文件,而不是读遍所有文件才理解项目结构。
反模式:只列文件、不写标注。TimerManager.swift无法告诉智能体它处理状态、UI,还是两者都处理。TimerManager.swift # Timer state, logic, and repeat handling则会明确告诉它哪些内容属于这里,哪些不属于。
3. 构建和测试命令
## Build & Test
Build for iOS simulator:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
```
Run tests:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Run tvOS tests:
```bash
xcodebuild -scheme ReturnTV -destination 'platform=tvOS Simulator,name=Apple TV' test
```
**Prefer MCP tools** (`build_sim`, `test_sim`) over these raw commands.
MCP returns structured JSON with categorized errors.
即使智能体应优先使用MCP,也要包含原始命令。原始命令可作为备用文档,并明确scheme名称和destination。
4. 关键模式和规则
## Key Patterns
### Observable Architecture
- ALL view models use `@Observable` (NEVER `ObservableObject`)
- ALL navigation uses `NavigationStack` (NEVER `NavigationView`)
- State management via `@Observable` classes with `@MainActor` isolation
### Settings Pattern
- Centralized `Settings.shared` singleton
- All settings bounded to valid ranges with validation
- Sound names validated against whitelist
- Thread-safe access via @MainActor
### Audio System
- `AVAudioPlayer` with `.playback` category (plays in silent mode)
- Silent audio loop for background execution
- Bell playback with completion callbacks and token-based staleness
这些模式可以防止智能体引入不一致。没有明确的模式文档时,智能体有时会在一个文件中使用ObservableObject,在另一个文件中使用@Observable,或者创建新的设置机制,而不是使用现有的Settings.shared单例。
5. 智能体绝不能做的事
## Rules
- **NEVER modify .pbxproj files** — create Swift files, then I will add them to Xcode manually
- **NEVER modify .xcodeproj/ contents directly**
- **NEVER add new package dependencies** without asking first
- **NEVER change the deployment target**
- **NEVER modify entitlements files** unless explicitly asked
- **NEVER use NavigationView** — always NavigationStack
- **NEVER use ObservableObject** — always @Observable
- **NEVER use @StateObject** — always @State with @Observable
明确的禁令比隐含期望更有效。智能体对负面约束的遵循通常更可靠,因为它们是二元判断(做/不做),而不是启发式判断(优先这个/有时用那个)。
6. 特定框架上下文
本节因应用而异。对于任何配置不直观的框架,都应包含本节:
对于HealthKit应用:
## HealthKit Configuration
- Entitlement: `com.apple.developer.healthkit`
- Info.plist keys:
- `NSHealthShareUsageDescription`: "Return reads your mindful minutes..."
- `NSHealthUpdateUsageDescription`: "Return logs meditation sessions..."
- Category types: `HKCategoryType(.mindfulSession)`
- Authorization checked on every write (user can revoke at any time)
- HealthKit is unavailable on tvOS — guard with `#if canImport(HealthKit)`
对于SwiftData应用:
## SwiftData Models
### Model Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList`
- `GroceryItem` has optional `Category`
### Model Container Setup
- Configured in App struct with `modelContainer(for:)`
- Schema versioning: currently V2
- Migration plan: `GroceryMigrationPlan` handles V1 → V2
### Queries
- `@Query(sort: \GroceryItem.name)` for sorted fetches
- `@Query(filter: #Predicate { !$0.isCompleted })` for active items
- Always use `@Query` in views, `modelContext.fetch()` in managers
对于SpriteKit应用:
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (SKNode, zPosition: -100)
│ └── StarfieldNode (custom, parallax scrolling)
├── gameLayer (SKNode, zPosition: 0)
│ ├── playerShip (PlayerNode, zPosition: 10)
│ ├── enemyContainer (SKNode, zPosition: 5)
│ └── bulletPool (SKNode, zPosition: 8)
├── effectsLayer (SKNode, zPosition: 50)
│ └── ParticleManager (manages explosion/trail emitters)
└── hudLayer (SKNode, zPosition: 100)
├── scoreLabel (SKLabelNode)
└── healthBar (HealthBarNode)
```
- Physics categories defined in `PhysicsCategory.swift` as bitmasks
- Contact detection via `didBegin(_ contact:)` on GameScene
- Bullet pooling: pre-allocate 50, recycle via `removeFromParent()` + re-add
对于Metal应用:
## Metal Pipeline
- Render pipeline: `MetalView` → `Renderer` → `ShaderLibrary`
- Compute pipeline: `AudioAnalyzer` → compute shader → texture output
- Shared uniforms struct: `Uniforms` in `ShaderTypes.h` (bridged to Swift)
- Frame timing: `CADisplayLink` drives render loop
- Buffer triple-buffering: 3 in-flight frames with semaphore
### Shader Files
- `Shaders.metal` — Main render shaders (vertex + fragment)
- `Compute.metal` — Audio analysis compute kernel
- `PostProcess.metal` — Bloom and color grading
### DO NOT modify Metal shaders without testing on device.
Simulator Metal is not representative of device GPU behavior.
真实CLAUDE.md:Banana List(SwiftUI + SwiftData + iCloud + MCP服务器)
下面是一个带标注的示例,展示这6个章节如何在一个中等复杂度应用中协同发挥作用。这是我在Banana List中使用的CLAUDE.md模式:它是一个包含53个文件的购物清单应用,支持iCloud同步,并带有一个自定义MCP服务器,可将应用数据提供给Claude Desktop:
# Banana List - Grocery List App
**Bundle ID:** `com.941apps.BananaList`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData + iCloud Drive sync
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
## Core Features
- Grocery lists with items, categories, and quantities
- iCloud Drive sync via SwiftData CloudKit integration
- Custom MCP server exposing list data to Claude Desktop
- Liquid Glass design system
- Haptic feedback on interactions
- Share sheets for list sharing
## File Structure
```
BananaList/
├── BananaListApp.swift # App entry, model container setup
├── Models/
│ ├── GroceryList.swift # @Model: list with name, items, color
│ ├── GroceryItem.swift # @Model: item with name, quantity, category, isCompleted
│ ├── Category.swift # @Model: user-defined categories
│ └── SampleData.swift # Preview and test data
├── Views/
│ ├── ListsView.swift # Main list of grocery lists
│ ├── ListDetailView.swift # Items within a list
│ ├── ItemRow.swift # Single item row with swipe actions
│ ├── AddItemSheet.swift # New item form
│ ├── CategoryPicker.swift # Category selection with create-new
│ └── SettingsView.swift # App settings
├── Managers/
│ ├── CloudSyncManager.swift # iCloud Drive sync status and conflict resolution
│ └── HapticManager.swift # UIImpactFeedbackGenerator wrapper
├── MCP/
│ ├── MCPServer.swift # MCP server for Claude Desktop integration
│ ├── ListTools.swift # MCP tools: list CRUD operations
│ └── ItemTools.swift # MCP tools: item CRUD operations
└── Extensions/
├── Color+Extensions.swift # Custom color definitions
└── View+Extensions.swift # Reusable view modifiers
```
## SwiftData Models
### Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList` (required)
- `GroceryItem` has optional `Category`
- `Category` has many `GroceryItem` (nullify on delete)
### Container Setup
```swift
@main
struct BananaListApp: App {
var body: some Scene {
WindowGroup {
ListsView()
}
.modelContainer(for: [GroceryList.self, GroceryItem.self, Category.self])
}
}
```
### Query Patterns
- Lists: `@Query(sort: \GroceryList.name) var lists: [GroceryList]`
- Active items: `@Query(filter: #Predicate { !$0.isCompleted })`
- By category: filter in-memory after fetch (SwiftData predicate limitations)
## Build & Test
```bash
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Prefer MCP tools (`build_sim`, `test_sim`) over raw commands.
## Key Patterns
### Observable + SwiftData
- SwiftData `@Model` classes are automatically Observable
- DO NOT add `@Observable` to `@Model` classes (redundant, causes warnings)
- Use `@Bindable` for two-way bindings to model properties in forms
- Use `@Query` in views, `modelContext.fetch()` in non-view code
### iCloud Sync
- Automatic via SwiftData CloudKit integration
- Conflict resolution: last-write-wins (CloudKit default)
- Sync status exposed via `CloudSyncManager.shared.syncState`
- Test sync by running on two simulators with same iCloud account
### MCP Server Architecture
- Runs as a local WebSocket server on port 8765
- Exposes 6 tools: listAll, getList, createList, addItem, completeItem, deleteItem
- Claude Desktop connects via MCP config in `~/.config/claude-desktop/config.json`
## Rules
- NEVER modify .pbxproj or .xcodeproj contents
- NEVER change the model schema without updating SampleData.swift
- NEVER use `ObservableObject` — SwiftData models are already Observable
- NEVER use `@StateObject` — use `@State` with `@Observable` classes
- NEVER use `NavigationView` — always `NavigationStack`
- NEVER add `@Observable` macro to `@Model` classes
- ALWAYS use `@Bindable` for form bindings to model properties
- ALWAYS test iCloud sync changes on two simulator instances
真实CLAUDE.md:Reps(最小SwiftData应用,14个文件)
对于小项目,CLAUDE.md可以很简洁。下面是Reps的模式,它是一个包含14个文件的健身训练记录应用。注意,即使是很短的CLAUDE.md,也覆盖了6个核心章节:
# Reps - Workout Tracking
**Bundle ID:** `com.941apps.Reps`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData
**Swift version:** 6.2
## File Structure
```
Reps/
├── RepsApp.swift # App entry, model container
├── Models/
│ ├── Workout.swift # @Model: workout with exercises, date, duration
│ ├── Exercise.swift # @Model: exercise with sets, reps, weight
│ └── ExerciseTemplate.swift # @Model: saved exercise definitions
├── Views/
│ ├── WorkoutListView.swift # Main list of workouts
│ ├── WorkoutDetailView.swift # Exercises within a workout
│ ├── ExerciseRow.swift # Single exercise with inline editing
│ ├── AddExerciseSheet.swift # Exercise selection from templates
│ ├── NewWorkoutView.swift # Start new workout flow
│ └── StatsView.swift # Progress charts and summaries
├── Managers/
│ └── WorkoutTimer.swift # Active workout timer
└── Extensions/
└── Date+Extensions.swift # Formatting helpers
```
## Build & Test
```bash
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## SwiftData Relationships
- `Workout` has many `Exercise` (cascade delete)
- `Exercise` has optional `ExerciseTemplate`
- `ExerciseTemplate` standalone (nullify on exercise delete)
## Rules
- NEVER modify .pbxproj
- NEVER use ObservableObject — use @Observable
- NEVER use NavigationView — use NavigationStack
- @Model classes are already Observable — do not add @Observable macro
- Use @Bindable for form bindings to model properties
对于一个14个文件的项目,这份CLAUDE.md只有40行。写它花10分钟,却能省下数小时的智能体困惑时间。
真实CLAUDE.md:Starfield Destroyer(SpriteKit + Metal,32个文件)
游戏项目需要更多特定框架上下文。智能体需要理解场景图、物理类别和游戏状态机:
# Starfield Destroyer - Space Shooter
**Bundle ID:** `com.941apps.StarfieldDestroyer`
**Target:** iOS 26+
**Architecture:** SpriteKit + Metal post-processing + Game Center
**Swift version:** 6.2
## Game Overview
99 levels across 3 galaxies. 8 unlockable ships with different stats.
Game Center leaderboards and achievements. Metal shader post-processing
for bloom and screen effects.
## File Structure
```
StarfieldDestroyer/
├── StarfieldDestroyerApp.swift # App entry, Game Center auth
├── GameScene.swift # Main game scene, update loop
├── MenuScene.swift # Title screen, ship selection
├── Entities/
│ ├── PlayerShip.swift # Player node with physics, weapons, shields
│ ├── EnemyShip.swift # Enemy base class with AI behaviors
│ ├── Bullet.swift # Bullet pool node
│ ├── PowerUp.swift # Collectible power-ups
│ └── Boss.swift # Boss enemies (levels 33, 66, 99)
├── Systems/
│ ├── LevelManager.swift # Level progression, wave spawning
│ ├── PhysicsCategory.swift # UInt32 bitmask categories
│ ├── CollisionHandler.swift # Contact delegate methods
│ ├── ScoreManager.swift # Score tracking, multipliers
│ ├── ParticleManager.swift # Explosion, trail, shield emitters
│ └── AudioManager.swift # Sound effects, background music
├── UI/
│ ├── HUDNode.swift # Score, health, level display
│ ├── ShipSelectView.swift # SwiftUI ship selection (UIHostingController)
│ ├── GameOverView.swift # Game over screen with score submission
│ └── PauseMenu.swift # Pause overlay
├── Metal/
│ ├── MetalRenderer.swift # Post-processing render pipeline
│ ├── BloomShader.metal # Bloom post-process effect
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Data/
│ ├── ShipData.swift # 8 ship definitions (speed, damage, shields)
│ ├── LevelData.swift # 99 level configurations
│ └── AchievementData.swift # Game Center achievement definitions
└── GameCenterManager.swift # Leaderboard/achievement submission
```
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (zPosition: -100)
│ └── StarfieldNode (parallax scrolling, 3 layers)
├── gameLayer (zPosition: 0)
│ ├── playerShip (zPosition: 10)
│ ├── enemyContainer (zPosition: 5)
│ ├── bulletPool (zPosition: 8) — pre-allocated 50 bullets
│ └── powerUpContainer (zPosition: 3)
├── effectsLayer (zPosition: 50)
│ └── ParticleManager (explosion + trail emitters)
└── hudLayer (zPosition: 100)
├── scoreLabel (SKLabelNode)
├── healthBar (custom SKShapeNode)
└── levelLabel (SKLabelNode)
```
## Physics Categories
```swift
struct PhysicsCategory {
static let none: UInt32 = 0
static let player: UInt32 = 0b1 // 1
static let enemy: UInt32 = 0b10 // 2
static let bullet: UInt32 = 0b100 // 4
static let powerUp: UInt32 = 0b1000 // 8
static let shield: UInt32 = 0b10000 // 16
static let bossBullet:UInt32 = 0b100000 // 32
}
// Contact pairs:
// player + enemy → damage
// player + powerUp → collect
// bullet + enemy → destroy
// player + bossBullet → damage
```
## Game State Machine
```
.menu → .playing → .paused → .playing
→ .gameOver → .menu
→ .bossIntro → .playing
→ .levelComplete → .playing (next level)
```
## Metal Post-Processing
- Bloom shader: `BloomShader.metal` — multi-pass Gaussian blur + additive blend
- Uniforms: `PostProcessUniforms { float intensity; float threshold; float2 resolution; }`
- Applied after SpriteKit renders each frame via `SKView.presentScene(:transition:)`
- DO NOT modify Metal shaders without testing on device
## Build & Test
```bash
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## Rules
- NEVER modify .pbxproj
- NEVER modify PhysicsCategory bitmasks (breaks all collision detection)
- NEVER change the scene hierarchy z-ordering without understanding render order
- NEVER modify ShaderTypes.h without updating both Swift and Metal references
- Add new enemies by subclassing EnemyShip, not by modifying it
- Bullet pooling: recycle via removeFromParent() + re-add, never allocate new
- Game Center: always check isAuthenticated before submitting scores
真实CLAUDE.md:amp97(Metal + 音频可视化,41个文件)
Metal项目最需要特定框架上下文,因为智能体无法验证视觉输出:
# amp97 - Audio Visualizer
**Bundle ID:** `com.941apps.amp97`
**Target:** iOS 26+
**Architecture:** Metal render pipeline + AVAudioEngine analysis
**Swift version:** 6.2
## Architecture
```
Audio Input (microphone/file)
→ AVAudioEngine tap
→ FFT (vDSP)
→ Frequency/amplitude buffers
→ Metal compute shader (analysis)
→ Metal render pipeline (visualization)
→ CADisplayLink (60fps)
→ MTKView
```
## File Structure
```
amp97/
├── amp97App.swift # App entry
├── Audio/
│ ├── AudioEngine.swift # AVAudioEngine setup, tap installation
│ ├── FFTProcessor.swift # vDSP FFT, frequency bin extraction
│ ├── AudioBuffer.swift # Ring buffer for audio data
│ └── MicrophoneManager.swift # Microphone permission, session config
├── Rendering/
│ ├── MetalView.swift # MTKView wrapper for SwiftUI
│ ├── Renderer.swift # Main render loop, pipeline state
│ ├── ShaderLibrary.swift # Compiled shader management
│ ├── BufferManager.swift # Triple-buffered uniform updates
│ └── TextureManager.swift # Offscreen render targets
├── Shaders/
│ ├── Shaders.metal # Vertex + fragment shaders
│ ├── AudioCompute.metal # Audio analysis compute kernel
│ ├── PostProcess.metal # Bloom, color grading
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Visualizations/
│ ├── WaveformViz.swift # Oscilloscope-style waveform
│ ├── SpectrumViz.swift # Frequency spectrum bars
│ ├── CircularViz.swift # Radial visualization
│ └── VizSelector.swift # Visualization switching
├── Views/
│ ├── MainView.swift # Full-screen viz with overlays
│ ├── ControlsOverlay.swift # Play/pause, viz selection, gain
│ └── SettingsView.swift # Audio source, sensitivity
└── Extensions/
├── SIMD+Extensions.swift # Vector math helpers
└── Color+Metal.swift # UIColor → float4 conversion
```
## Metal Pipeline
### Uniforms (ShaderTypes.h)
```c
typedef struct {
float time;
float2 resolution;
float audioLevel; // 0.0-1.0 RMS amplitude
float frequencyBins[64]; // FFT output, normalized
float4x4 transform;
} Uniforms;
```
### Render Pipeline
1. Compute pass: AudioCompute.metal processes FFT data → texture
2. Render pass: Shaders.metal reads texture + uniforms → visualization
3. Post-process pass: PostProcess.metal applies bloom → final output
### Buffer Management
- Triple buffering with DispatchSemaphore(value: 3)
- Uniforms updated per-frame on CPU, consumed by GPU 1-2 frames later
- Audio data ring buffer: 4096 samples, lock-free single producer/consumer
## Rules
- NEVER modify ShaderTypes.h without updating BOTH Swift and Metal sides
- NEVER exceed 64 frequency bins (fixed buffer size in shader)
- NEVER test Metal visual output in simulator — device only
- NEVER modify the audio engine tap format (48kHz, mono, float32)
- Triple buffer discipline: always signal semaphore in completion handler
- Audio session: .playAndRecord category with .defaultToSpeaker option
根据项目规模扩展CLAUDE.md
合适的详细程度取决于文件数量和框架复杂度:
| 项目规模 | CLAUDE.md深度 | 示例 |
|---|---|---|
| 小型(<20个文件) | 身份信息+文件列表+规则 | Reps(14个文件):基本SwiftData模式、构建命令、禁止事项 |
| 中型(20-40个文件) | +框架上下文+关键模式 | TappyColor(30个文件):SpriteKit场景层级、物理类别、游戏循环 |
| 大型(40+个文件) | +架构图+关系映射+多目标信息 | Return(63个文件):跨平台架构、会话同步图、各平台差异 |
| 专用型(Metal/GPU) | +管线图+共享类型定义+缓冲区布局 | amp97(41个文件):渲染管线阶段、uniform结构体、缓冲区管理 |
文档写得过多,成本几乎为零(智能体会跳过不需要的内容)。文档写得不足,成本很高(智能体会发明与代码库冲突的模式)。
CLAUDE.md检查清单
创建或审计iOS项目的CLAUDE.md时,请使用此清单:
- [ ] 已指定Bundle ID和部署目标
- [ ] 已命名Swift版本和架构模式
- [ ] 文件结构包含内联用途标注
- [ ] 构建命令包含正确的scheme和destination
- [ ] 测试命令包含正确的scheme和destination
- [ ] 已注明MCP偏好(”prefer build_sim over xcodebuild”)
- [ ] @Observable规则(绝不使用ObservableObject)
- [ ] NavigationStack规则(绝不使用NavigationView)
- [ ] .pbxproj禁令
- [ ] 特定框架上下文(HealthKit权限、SwiftData关系、SpriteKit层级、Metal管线)
- [ ] 已记录平台可用性保护(#if canImport、#if os)
- [ ] 已记录关键单例和共享模式
- [ ] 已注明已知限制或易错点
您的第一次智能体会话
在配置好MCP,并且项目中已有 CLAUDE.md 后,下面是一段高效首次会话的演练。这里使用Claude Code CLI,但该工作流适用于任何运行时。
第1步:验证智能体能否看到您的项目
You: Summarize this project. What scheme should I build with?
Claude: [reads CLAUDE.md]
[calls discover_projs via MCP]
[calls list_schemes via MCP]
This is Return, a zen meditation timer for iOS 26+, watchOS, and tvOS.
Available schemes: Return, ReturnWatch, ReturnTV, ReturnTests.
Primary scheme for iOS: Return.
如果智能体没有引用您的 CLAUDE.md 内容,请检查该文件是否位于项目根目录(与.xcodeproj或Package.swift同一目录)。
第2步:运行健康检查构建
You: Build the Return scheme for iOS simulator and report results.
Claude: [calls list_sims — finds iPhone 16 Pro on iOS 26.2]
[calls boot_sim — boots the simulator]
[calls build_sim — builds the project]
Build succeeded. 63 source files compiled.
2 warnings:
- HomeView.swift:132 — UIScreen.main deprecated in iOS 26.0
- LogWaterIntent.swift:61 — Result of try? is unused
0 errors.
第3步:运行测试
You: Run all tests and report pass/fail.
Claude: [calls test_sim]
12 tests executed:
✓ TimerManagerTests (5/5 passed)
✓ SettingsTests (4/4 passed)
✓ ConstantsTests (3/3 passed)
All tests passed.
第4步:实现一项功能
You: Add a new "Rain" theme to the theme system. Follow the existing
pattern in Theme.swift and ThemeManager.swift. Include a rain
ambient sound. Build and test after implementation.
Claude: [reads Theme.swift — understands Theme struct pattern]
[reads ThemeManager.swift — understands theme registration]
[reads existing theme definitions]
[adds Rain theme to Theme.swift following existing pattern]
[registers Rain theme in ThemeManager.swift]
[calls build_sim — build succeeds]
[calls test_sim — all tests pass]
Added Rain theme:
- Theme.swift: new `static let rain` with video, cover, ambient
- ThemeManager.swift: added to `allThemes` array
- Build: success (0 errors, 2 existing warnings)
- Tests: 12/12 passed
Note: You'll need to add rain_ambient.wav to the project
and add the new Theme.swift changes to the Xcode target manually
(I did not modify .pbxproj).
智能体关于不修改 .pbxproj 的说明,来自 CLAUDE.md 中的规则。没有这条规则,智能体会尝试修改项目文件,而且很可能导致文件损坏。
智能体在 iOS 中擅长做什么
以下任务中,智能体通常能稳定产出正确、可用于生产的结果,并且只需很少的人工审查。
SwiftUI 视图和修饰符
智能体对 SwiftUI 声明式语法具备很强的模式识别能力。视图组合、修饰符链、状态绑定和布局——这些都非常适合智能体的训练数据,因为 SwiftUI 的API表面文档完善,模式也高度一致。
智能体擅长的场景:
- 根据描述构建新视图(“创建一个设置表单,其中包含 X、Y、Z 的开关”)
- 应用修饰符链(.glassEffect()、.sensoryFeedback()、.navigationTitle())
- 在不同布局模式之间转换(VStack 到 LazyVGrid,List 到 ScrollView)
- 为 SwiftData 模型实现@Bindable表单绑定
- 使用示例数据构建预览提供器
能够产生优秀结果的示例提示:
Create a SettingsView that matches the existing pattern in SettingsSheet.swift.
Include toggles for:
- Enable haptic feedback (Settings.shared.hapticsEnabled)
- Enable HealthKit logging (Settings.shared.healthKitEnabled)
- Show session history (navigation link to SessionHistoryView)
Use Liquid Glass styling with .glassEffect() on section backgrounds.
Follow the @Observable pattern, not ObservableObject.
具体程度很重要。“Create a settings view”会产生通用输出。“Create a SettingsView that matches the existing pattern in SettingsSheet.swift”则会产生与代码库一致的输出。
SwiftData 模型和查询
智能体能够可靠处理 SwiftData 的@Model宏、关系和@Query模式。该框架的声明式特性(类似 Django ORM 或 SQLAlchemy)与智能体在大量代码库中见过的模式高度契合。
智能体擅长的场景:
- 定义带关系的@Model类
- 编写带排序描述符和谓词的@Query
- 通过modelContext实现 CRUD 操作
- 制定 schema 版本之间的迁移计划
- 预览数据和测试夹具
智能体需要指导的场景:
- 复杂的#Predicate表达式(SwiftData 的谓词 DSL 存在一些限制,智能体并不总是了解——请在 CLAUDE.md 中记录已知限制)
- CloudKit 同步配置(SwiftData 会自动处理,但智能体可能会尝试实现手动同步)
单元测试
智能体为 iOS 项目编写的单元测试质量一贯较高。它理解 XCTest 模式、async 测试方法,以及 setup/teardown 生命周期。
Write unit tests for TimerManager covering:
1. Initial state is .stopped
2. start() transitions to .running
3. pause() transitions to .paused
4. reset() returns to .stopped with original duration
5. Timer counts down correctly (test with 3-second duration)
智能体会生成结构清晰的 XCTest 用例,包含setUp()和tearDown()、恰当的断言,以及针对基于定时器测试的 async 处理。
重构和模式应用
智能体擅长机械式重构:将视图提取为组件、将ObservableObject转换为@Observable、从NavigationView迁移到NavigationStack,并在多个文件中应用一致模式。
Refactor all views in the Views/ directory to use @Observable instead of
ObservableObject. Update @StateObject to @State, @ObservedObject to direct
property access, and @Published to plain properties.
智能体会有条不紊地处理每个文件,正确应用转换,并保持现有功能不变。这类工作杠杆很高——原本需要手动编辑一小时的重构,几分钟内即可完成,而且准确率接近完美。
通过MCP诊断构建错误
借助结构化的MCP输出,智能体诊断构建错误的速度比大多数开发者更快。智能体会读取错误JSON,定位到确切的文件和行,理解错误消息,并应用修复——通常一轮即可完成。
智能体可自主修复的错误: - 缺少 import - 类型不匹配 - 协议遵循缺口 - 使用已弃用的API(并替换为新写法) - 缺少必需的初始化参数 - 访问控制违规
智能体需要帮助的错误: - 类型解析存在歧义(多个模块定义了同一类型) - 复杂的泛型约束失败 - 宏展开错误(智能体无法看到展开后的宏输出)
Simulator 管理
智能体可通过MCP很好地处理 Simulator 生命周期:
Boot an iPhone 16 Pro simulator on iOS 26, install the app, and take a screenshot.
智能体会调用list_sims查找可用运行时,调用boot_sim启动模拟器,调用build_sim进行构建和安装,并调用screenshot捕获截图——所有操作都通过结构化MCP调用完成。
智能体在iOS中不擅长的事
如实说明智能体会在哪些地方失败。了解这些边界,可以避免挫败感和token浪费。
.pbxproj文件修改——绝对不要
这是iOS智能体开发中最重要的一条规则。.pbxproj文件是Xcode的项目配置,即一个包含UUID引用、构建阶段列表和target成员关系的结构化文本文件。它名义上可供人类阅读,但对AI智能体来说,实际几乎无法解析。
智能体为什么会在.pbxproj上失败: - 该文件使用自定义格式(不是JSON,不是YAML,也不是XML),且位置具有语义意义 - 每个条目都通过UUID交叉引用——添加一个文件需要在3-5个不同部分保持一致地更新 - 一个字符放错位置,就会损坏整个项目文件 - Xcode对.pbxproj的合并冲突处理本就脆弱,智能体编辑会让情况更糟
智能体编辑.pbxproj后会发生什么: 1. 编辑看起来成功了(智能体报告“文件已更新”) 2. Xcode拒绝打开项目(“The project file is corrupted”) 3. 您花15-60分钟从git历史中恢复 4. 您学会添加PreToolUse hook(参见Hooks)
工作流:智能体创建Swift文件。您手动将它们添加到Xcode项目中(拖入Xcode,或使用File > Add Files)。每个文件只需5秒,却能避免数小时的恢复工作。
对于Swift Package Manager项目:这个限制没那么严重。Package.swift是标准Swift文件,智能体可以可靠地编辑。如果您的项目完全使用SPM(没有.xcodeproj),智能体就可以管理完整项目结构。
复杂的Interface Builder/Storyboard编辑
如果项目使用Interface Builder(.xib文件)或Storyboards(.storyboard文件),智能体无法进行有意义的编辑。这些XML文件包含自动生成的UUID、约束引用和outlet连接,本就是为可视化编辑设计的,不适合文本编辑。
缓解方式:新视图全部使用SwiftUI。如果项目中有遗留Interface Builder文件,不要动它们,新UI用SwiftUI构建。
性能优化
智能体会写出正确代码,但不一定是高性能代码。它们无法分析您的app、识别瓶颈或测量帧率。性能优化需要:
- Instruments分析(可视化工具,智能体无法访问)
- 理解特定设备的GPU/CPU特性
- 基于测量结果进行迭代修改
常见表现: - Metal shader优化(智能体能写出有效的Metal,但无法测量GPU帧时间) - SwiftUI view body复杂度(智能体会创建层层嵌套的视图,导致重绘开销) - Core Data/SwiftData获取优化(智能体写出的查询是正确的,但在大数据集上可能很慢)
缓解方式:用智能体做实现,手动用Instruments进行分析,然后让智能体应用您已确认的具体优化。
代码签名和Provisioning
除了读取错误消息,智能体无法调试代码签名问题。Provisioning profile管理、证书创建、entitlement配置和App Store提交,本质上都是需要人来操作的工作流,涉及Apple Developer门户、Keychain Access以及Xcode的签名UI。
智能体看到的是:“Signing for ‘Return’ requires a development team.”
智能体看不到的是:您的证书是否过期、provisioning profile是否包含该设备、bundle ID是否匹配App ID,或entitlements文件是否正确。
缓解方式:所有签名工作都在Xcode的Signing & Capabilities标签页中处理。不要让智能体调试签名失败。
复杂的Metal Shader调试
智能体能写出语法正确的Metal Shading Language(MSL),但无法验证视觉输出,也无法调试GPU侧问题。Metal shader在GPU上执行,智能体没有反馈机制来判断shader是否产生了正确的视觉结果。
智能体可以用Metal做什么:
- 根据描述编写vertex和fragment shader
- 在Swift中设置Metal渲染管线
- 为数据并行操作创建compute shader
- 修复.metal文件中的编译错误
智能体不能用Metal做什么: - 验证shader输出的视觉正确性 - 调试GPU性能(帧时间、occupancy、内存带宽) - 诊断视觉瑕疵(色带、精度问题、错误的色彩空间) - 在不同GPU架构上测试(A系列与M系列的行为差异)
缓解方式:在真机上测试Metal shader。Simulator的Metal实现不能代表设备GPU行为。使用Xcode的GPUFrame Capture进行视觉调试。
视觉布局验证
智能体看不到您的app UI。它们会编写SwiftUI布局代码,并能验证代码是否编译通过,但无法判断最终屏幕看起来是否正确。一个视图即使偏离中心10像素、用了错误的字体粗细,或元素相互重叠,也不会产生构建错误,并且会通过所有逻辑测试。
缓解方式:目视检查UI改动。使用Xcode中的SwiftUI Previews(或通过Apple MCP使用RenderPreview进行无头渲染)来验证布局。可以考虑使用swift-snapshot-testing等库进行snapshot testing,以自动检测视觉回归。
用于iOS开发的Hooks
Hooks是在智能体工作流的特定节点以确定性方式执行的shell命令。它们是强制执行机制——区别在于,“请不要编辑.pbxproj”只是建议,智能体可能忽略;而“您不能编辑.pbxproj”则是硬性阻止。
如需了解hook系统背景,请参阅Claude Code hooks指南。本节介绍iOS专用hook模式。
PreToolUse:阻止写入.pbxproj
这是任何iOS项目中最重要的hook。它会阻止智能体写入.pbxproj文件、.xcodeproj/目录以及其他由Xcode管理的文件:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files. Create Swift files and add to Xcode manually.\" >&2; exit 2; fi'"
}
]
}
}
将其放在项目根目录的.claude/settings.json中,或放在~/.claude/settings.json中以提供全局保护。
工作原理:当智能体尝试对任何匹配该模式的文件使用Edit或Write工具时,hook会运行,检测文件路径,向stderr打印警告,并以代码2退出(这会阻止工具调用)。智能体会收到错误消息,并调整处理方式。
它会捕获:
- 直接编辑.pbxproj
- .xcodeproj/或.xcworkspace/目录中的任何文件
- Interface Builder文件(.xib、.storyboard)
PostToolUse:使用SwiftFormat实现保存时格式化
每当智能体写入或编辑Swift文件时,自动格式化这些文件:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
要求:必须安装SwiftFormat(brew install swiftformat)。
为什么这很重要:智能体能生成语法正确的Swift,但并不总能遵循格式约定。SwiftFormat会规范缩进、大括号位置和import排序。保存时格式化hook意味着,智能体触碰过的每个Swift文件,都会在您看到之前自动完成格式化。
可选:在项目根目录添加.swiftformat配置文件,用于自定义格式化规则:
# .swiftformat
--indent 4
--allman false
--stripunusedargs closure-only
--importgrouping testable-bottom
--header strip
PostToolUse:自动运行SwiftLint
如果使用SwiftLint,请在每次编辑Swift文件后运行它:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftlint lint --path \"$FP\" --quiet 2>/dev/null || true; fi'"
}
]
}
}
|| true会防止lint警告阻塞智能体。如果希望lint违规阻塞流程,请移除它。
PostToolUse:变更后自动构建
对于更激进的反馈循环,可以在每次Swift文件变更后触发构建:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then xcodebuild -scheme Return -destination \"platform=iOS Simulator,name=iPhone 16 Pro\" build 2>&1 | tail -5; fi'"
}
]
}
}
警告:这会带来较高开销。每次文件编辑都会触发一次构建。请谨慎使用——它最适合用于调试会话,此时您需要即时构建反馈。对于常规开发,让智能体在准备好后通过MCP手动触发构建即可。
PreToolUse:阻止修改Entitlements
保护您的entitlements文件,避免智能体意外修改:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.entitlements$\"; then echo \"BLOCKED: Do not modify entitlements files without explicit permission.\" >&2; exit 2; fi'"
}
]
}
}
组合式iOS Hook配置
以下是我在所有iOS项目中使用的完整.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard|entitlements)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode-managed files. Create Swift files and add manually.\" >&2; exit 2; fi'"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
这会提供两项保障: 1. 智能体无法损坏Xcode项目文件(PreToolUse阻止) 2. 智能体触碰的每个Swift文件都会自动格式化(PostToolUse格式化)
适合智能体协作的架构模式
并非所有Swift架构都同样适合智能体。这些模式效果最好,因为它们明确、一致,并且在训练数据中有充分体现。
@Observable(绝不使用ObservableObject)
面向iOS 26+的目标应仅使用@Observable。这既是现代模式,也是对智能体友好的模式:
// CORRECT — @Observable
@Observable
@MainActor
final class TimerManager {
var timeRemaining: TimeInterval = 0
var state: TimerState = .stopped
func start() {
state = .running
// ...
}
}
// In a view:
struct TimerView: View {
@State private var timer = TimerManager()
var body: some View {
Text(timer.timeRemaining, format: .number)
}
}
// WRONG — ObservableObject (deprecated pattern)
class TimerManager: ObservableObject {
@Published var timeRemaining: TimeInterval = 0
@Published var state: TimerState = .stopped
}
// WRONG — @StateObject (deprecated pattern)
struct TimerView: View {
@StateObject private var timer = TimerManager()
}
为什么@Observable对智能体友好:该模式更简单(无需@Published注解),所有权模型更清晰(使用@State,而不是在@StateObject与@ObservedObject之间取舍),并且由于活动部件更少,智能体使用它时产生的 bug 更少。
在CLAUDE.md中记录这一点:即使目标是iOS 26,智能体偶尔也会回到其训练数据中的ObservableObject模式。明确禁止可以防患于未然。
NavigationStack(绝不使用NavigationView)
// CORRECT
NavigationStack {
List(items) { item in
NavigationLink(value: item) {
ItemRow(item: item)
}
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
// WRONG
NavigationView {
List(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
ItemRow(item: item)
}
}
}
NavigationStack支持iOS 16+,也是新代码唯一应使用的导航模式。类型安全的navigationDestination(for:)模式可以防止智能体创建错误的导航链接。
使用SwiftData实现持久化
SwiftData模型是智能体辅助开发中最清晰的持久化模式:
@Model
final class GroceryItem {
var name: String
var quantity: Int
var isCompleted: Bool
var category: Category?
var list: GroceryList?
init(name: String, quantity: Int = 1) {
self.name = name
self.quantity = quantity
self.isCompleted = false
}
}
智能体使用SwiftData时的关键规则:
1. @Model类会自动成为Observable——不要添加@Observable
2. 表单绑定使用@Bindable:@Bindable var item: GroceryItem
3. 视图中的响应式数据使用@Query:@Query var items: [GroceryItem]
4. 非视图代码中使用modelContext.fetch()
5. 关系删除需要明确规则:.cascade、.nullify、.deny
Swift 6.2并发
新项目应以Swift 6.2严格并发为目标:
// Actor isolation for shared mutable state
@MainActor
@Observable
final class DataManager {
var items: [Item] = []
func loadItems() async throws {
let fetched = try await api.fetchItems()
items = fetched // Safe: @MainActor isolated
}
}
// Sendable conformance for cross-actor transfers
struct Item: Sendable, Identifiable {
let id: UUID
let name: String
let createdAt: Date
}
面向智能体的并发指导:
- 将所有视图模型标记为@MainActor(防止数据竞争警告)
- 所有异步工作都使用async/await(不要使用 completion handler)
- 为跨 actor 传递的值类型添加Sendable
- 在视图中使用Task { }进行异步初始化
- 只有在已衡量出性能需求时,才使用nonisolated
Liquid Glass设计系统(iOS 26+)
iOS 26引入了Liquid Glass设计系统。只要给出明确指导,智能体就能很好地处理它:
// Glass effect on containers
VStack {
// content
}
.glassEffect()
// Glass effect with tint
Button("Action") { }
.glassEffect(.regular.tint(.blue))
// Glass effect on navigation bars (automatic in iOS 26)
NavigationStack {
// content
}
// Navigation bar automatically uses glass material
// Custom glass shapes
RoundedRectangle(cornerRadius: 16)
.fill(.ultraThinMaterial)
.glassEffect()
写入CLAUDE.md:“在分区背景和卡片容器上使用.glassEffect()。导航栏在iOS 26中会自动采用 glass material。不要用自定义材质手动重建 glass 效果——请使用系统 modifier。”
框架特定上下文
每个Apple框架都有需要针对智能体考虑的事项。本节涵盖这8款 app 中使用的框架。
HealthKit
使用它的 app:Return、Water
HealthKit需要谨慎处理权限,并添加平台保护:
// Always check availability and authorization
import HealthKit
@MainActor
@Observable
final class HealthKitManager {
private let store = HKHealthStore()
var isAuthorized = false
func requestAuthorization() async {
guard HKHealthStore.isHealthDataAvailable() else { return }
let types: Set<HKSampleType> = [
HKQuantityType(.dietaryWater),
HKCategoryType(.mindfulSession)
]
do {
try await store.requestAuthorization(toShare: types, read: types)
isAuthorized = true
} catch {
// User denied — do not retry automatically
}
}
}
智能体使用HealthKit时的规则:
- 始终使用HKHealthStore.isHealthDataAvailable()进行保护
- 永远不要假设已获得授权——每次写入都要检查
- 多平台代码使用#if canImport(HealthKit)(tvOS不支持HealthKit)
- 除HealthKit提供的数据外,不要在本地存储健康数据
- 在Info.plist中同时包含NSHealthShareUsageDescription和NSHealthUpdateUsageDescription
SpriteKit
使用它的 app:TappyColor、Starfield Destroyer
SpriteKit的场景图模型需要给智能体明确指导:
## SpriteKit Rules
- Scene hierarchy is a tree of SKNodes with zPosition ordering
- Physics bodies use category bitmasks (UInt32) for collision detection
- Node pooling: pre-allocate reusable nodes (bullets, particles)
- Never add nodes directly to the scene — use layer nodes for organization
- Update loop: `update(_ currentTime:)` runs every frame — keep it fast
- Actions: use SKAction sequences for animations, not manual property updates
- Textures: use texture atlases for performance (.atlas directories)
智能体在SpriteKit中的优势: - 创建SKAction序列和分组 - 设置物理实体和接触检测 - 实现游戏状态机 - 构建HUD叠加层
智能体在SpriteKit中的短板: - 对性能敏感的游戏循环(智能体会在每帧添加不必要的工作) - 复杂物理模拟(若追求精度,自定义物理优于SKPhysicsBody) - 粒子效果调优(偏视觉,需要迭代)
Metal
使用它的 app:amp97、Water、Starfield Destroyer
Metal是智能体最容易遇到困难的框架。GPU编程模型与CPU侧Swift有本质差异,而且智能体无法验证视觉输出。
## Metal Rules
- Shared types between Swift and Metal go in a bridging header (ShaderTypes.h)
- Triple buffer in-flight frames (semaphore with value 3)
- Test shaders on DEVICE, not simulator (Metal behavior differs)
- Compute shaders: threadgroup size must divide evenly into grid size
- Fragment shaders: output color must be in correct color space (sRGB or linear)
- DO NOT optimize shaders without Instruments GPU profiling data
Metal项目的CLAUDE.md中应包含: - Uniforms结构体定义(Swift与MSL共享) - 渲染管线状态设置模式 - Buffer索引及其用途 - 已存在的 shader,以及每个 shader 的作用 - 已知精度问题(half与float)
Live Activities
使用它的 app:Return
Live Activities需要特定配置;一旦记录清楚,智能体就能很好地处理:
## Live Activities
- ActivityAttributes defined in `TimerActivityAttributes.swift`
- ActivityKit framework: `import ActivityKit`
- Widget extension: `ReturnWidgets/ReturnLiveActivity.swift`
- Start: `Activity<TimerActivityAttributes>.request(attributes:content:)`
- Update: `activity.update(ActivityContent(state:staleDate:))`
- End: `activity.end(ActivityContent(state:staleDate:), dismissalPolicy:)`
- Push token: register for updates via `activity.pushTokenUpdates`
Game Center
使用它的 app:Starfield Destroyer
## Game Center
- Authentication: `GKLocalPlayer.local.authenticateHandler`
- Leaderboards: `GKLeaderboard.submitScore(_:context:player:leaderboardIDs:completionHandler:)`
- Achievements: `GKAchievement.report(_:withCompletionHandler:)` (takes `[GKAchievement]` array)
- Always check `GKLocalPlayer.local.isAuthenticated` before submitting
- Handle authentication failure gracefully (offline play must work)
多平台模式
Return横跨iOS、watchOS和tvOS。借助智能体进行多平台开发时,需要明确记录平台边界。
共享代码组织
Shared/
├── MeditationSession.swift # Data model (all platforms)
├── SessionStore.swift # iCloud sync (all platforms)
└── SessionHistoryView.swift # UI (adapts per platform)
Return/ # iOS-specific
ReturnWatch Watch App/ # watchOS-specific
ReturnTV/ # tvOS-specific
智能体规则:“如果文件位于Shared/中,变更会影响所有平台。如果文件位于某个平台目录中,变更则相互隔离。修改文件前,务必先检查它所在的目录。”
平台可用性保护
// HealthKit: available on iOS and watchOS, not tvOS
#if canImport(HealthKit)
import HealthKit
// HealthKit code here
#endif
// ActivityKit: available on iOS only
#if canImport(ActivityKit)
import ActivityKit
// Live Activity code here
#endif
// WatchKit: available on watchOS only
#if os(watchOS)
import WatchKit
// Watch-specific code here
#endif
智能体指导:“使用平台特定框架时,始终使用#if canImport()或#if os()保护。不要假设某个框架在所有目标上都可用。”
按平台调整UI
struct SessionHistoryView: View {
@Query var sessions: [MeditationSession]
var body: some View {
List(sessions) { session in
SessionRow(session: session)
}
#if os(tvOS)
.focusable()
#endif
#if os(iOS)
.swipeActions {
Button("Delete", role: .destructive) {
// delete
}
}
#endif
}
}
高级工作流
自主构建-测试-修复循环
最强大的模式:向智能体提供功能规范,并让它自主迭代构建-测试-修复循环。
Implement a countdown timer that:
1. Starts from a user-selected duration (10, 20, or 30 minutes)
2. Shows remaining time with a circular progress indicator
3. Plays a bell sound on completion
4. Logs the session to HealthKit as mindful minutes
Build after each change. Fix all errors. Run tests when the build succeeds.
Continue until all tests pass and the build is clean.
智能体编写代码,通过MCP构建,读取结构化错误,修复问题,然后重复此过程。一个原本需要人工经历5-10轮构建-错误-修复循环的功能,可以在一次自主循环中完成。
适用场景:验收标准清晰、定义明确的功能。
失效场景:开放式功能(“让它好看一些”)、性能敏感代码,或任何需要视觉验证的内容。
iOS中的子智能体委派
Claude Code的子智能体系统适用于iOS项目:
Use a subagent to research the best approach for implementing
iCloud key-value store sync for meditation sessions across iOS,
watchOS, and tvOS. Report back with the recommended pattern.
子智能体在独立上下文窗口中探索文档和代码模式,返回摘要,主会话再实施建议。这样可以避免研究工作消耗您的主上下文。
跨App模式应用
如果您维护多个采用一致模式的iOS应用,智能体可以将一个应用中的模式应用到另一个应用:
Look at how Settings.swift works in the Return project
(centralized singleton with validation). Apply the same pattern
to create a Settings.swift for the Water project.
智能体会读取源模式,理解其结构,并在目标项目中创建一致的实现。
双智能体审查(Claude + Codex)
对于关键变更,使用来自不同模型家族的两个智能体:
- Claude Code编写实现
- Codex CLI在单独轮次中进行审查
# After Claude implements the feature:
codex "Review the changes in the last commit. Focus on Swift 6.2
concurrency correctness, SwiftData relationship integrity,
and potential retain cycles. Report issues only — no praise."
不同模型家族会捕获不同类型的错误。这对Metal着色器和并发模式尤其有价值,因为这类代码很容易引入隐蔽缺陷。
双重审查能发现而单次审查容易遗漏的问题:
| 问题类型 | Claude优势 | Codex优势 |
|---|---|---|
| SwiftData关系循环 | 中等 | 强(GPT-4o) |
| @MainActor隔离缺口 | 强 | 中等 |
| Metal缓冲区对齐 | 中等 | 中等 |
| 保留循环检测 | 强(Opus) | 强(o3) |
| API弃用感知 | 强(训练数据较新) | 中等 |
| 并发竞态条件 | 强 | 强(可捕获不同模式) |
双重审查的重点不是找出更多错误,而是找出不同的错误。每个模型家族在模式识别上都有不同的失效模式。
跨多个App的批量操作
当某个框架或模式变更会影响多个应用时:
# Update @Observable pattern across all projects
for project in BananaList Return Water Reps; do
cd ~/Projects/$project
claude -p "Audit all files for any remaining ObservableObject usage.
Convert to @Observable following the pattern in CLAUDE.md.
Build and test after changes." --dangerously-skip-permissions
done
谨慎使用。非交互模式需要--dangerously-skip-permissions标志,但它会绕过所有安全检查。请确保已设置PreToolUse钩子,以保护.pbxproj文件。
使用Apple端侧LLM的App
如果您的应用调用Apple的Foundation Models框架(例如用于离线摘要、分类或结构化输出生成),智能体需要知道提示词预算。iOS 26.4为SystemLanguageModel新增了两个API,取代了此前4096token的估算:contextSize(模型在单次对话中接受的最大token数)和tokenCount(for:)(async throws,返回给定提示词实际消耗的token数量)。17二者都是@backDeployed(before: iOS 26.4),因此无需#available阶梯判断,就能在所有支持FM的OS版本上使用。
智能体生成提示词构造代码时应遵循以下模式:
import FoundationModels
func budgetFor(prompt: String, reservedReply: Int = 256) async throws -> Int {
let model = SystemLanguageModel.default
let promptCost = try await model.tokenCount(for: prompt)
let budget = model.contextSize - promptCost - reservedReply
guard budget > 0 else { throw ContextError.promptTooLong }
return budget
}
如果应用涉及SystemLanguageModel,请将此模式添加到CLAUDE.md。否则,智能体会退回到旧的4096硬编码,并在搭载更大上下文窗口的设备上静默截断提示词。tokenCount(for:)的async throws签名至关重要,粘贴同步版本的智能体将无法通过编译。
真实案例研究
抽象建议很容易写。下面是来自这8款应用的具体场景,展示agent辅助的iOS开发在实践中如何运作,包括失败案例。
案例研究1:为Return添加TV应用(成功)
任务:为Return添加tvOS target。Return是一款冥想计时器,已有iOS和watchOS版本。TV应用需要支持Siri Remote导航、大屏UI,以及与iOS应用同步设置。
agent做得好的地方:
- 阅读现有iOS TimerManager,并创建了一个TVTimerManager,省略了tvOS不可用的Live Activities和HealthKit
- 为Siri Remote焦点导航创建了自定义按钮样式(TVCapsuleButtonStyle、TVCircleButtonStyle)
- 构建了TVStepper组件,用+/-按钮替代滚轮选择器(Siri Remote无法使用滚轮选择器)
- 通过App Groups(group.com.941apps.Return)实现设置同步
- 在共享代码中添加了#if os(tvOS)防护
- 通过MCP使用platform=tvOS Simulator,name=Apple TV进行构建和测试
我必须手动完成的工作: - 在Xcode中创建tvOS target(File > New > Target > tvOS App) - 将新target添加到Xcode项目中(.pbxproj变更) - 为TV target配置App Groups entitlement - 将TV target添加到现有scheme,或创建新的scheme - 手动将所有agent创建的Swift文件添加到TV target - 手动测试Siri Remote导航(agent无法评估焦点行为)
结果:新增15个Swift文件,TV应用功能完整,agent辅助工作耗时约3小时。据我估计,agent承担了大约80%的实现工作;我处理了需要Xcode UI交互的部分(entitlements、target设置、capability flags),并在真实Apple TV上手动测试焦点。基于我在这个代码库中未使用agent交付类似功能的经验,等量的单人工作通常需要数天。
案例研究2:amp97中的Metal Shader调试(部分失败)
任务:为示波器shader添加基于能量的强度系统。可视化效果应随音频能量脉动。
发生了什么:
1. agent编写了有效的Metal shader修改,添加了uEnergyuniform和HDR tonemapping
2. 代码编译无误
3. 在设备上,可视化效果完全变白,因为强度系数高了10倍(3.5而不是0.30)
4. agent看不到白屏,因此没有反馈信号
5. 我通过视觉确认了问题,并要求agent降低系数
6. agent降低了系数,但整体能量状态机过于复杂,以不同方式破坏了可视化器
7. 完全回滚,两个commit(67959ed和cda4830)在869d914中被回滚
经验教训:Metal shader是agent辅助开发中最困难的领域,因为反馈循环是断开的。agent可以验证语法(能编译)和语义(类型正确),但无法验证输出(看起来是否正确)。任何会改变视觉行为的shader修改,都需要人在设备上验证。
此后我添加到CLAUDE.md中的内容:“DO NOT attempt energy state modifications to the oscilloscope shader without extremely careful coefficient testing. Previous attempt broke the visualizer with coefficients 10x too high.”
案例研究3:Banana List中的SwiftData迁移(成功)
任务:将数据模型从V1迁移到V2,为GroceryItem添加quantity字段,并添加带关系的新Category模型。
agent做了什么:
1. 阅读现有V1模型定义
2. 创建带有新字段和关系的V2模型定义
3. 编写符合SchemaMigrationPlan协议的GroceryMigrationPlan
4. 实现V1toV2迁移阶段:添加默认quantity: 1和category: nil
5. 更新所有视图以支持新字段
6. 更新SampleData.swift用于预览
7. 通过MCP构建并运行测试,全部通过
8. 创建迁移专用单元测试
关键点:agent之所以成功,是因为SwiftData迁移遵循定义明确的协议模式,并且Apple文档和训练数据中都有充分体现。CLAUDE.md明确记录了V1模型,因此agent理解自己正在从什么迁移。
案例研究4:Return中的iCloud会话同步(成功但复杂)
任务:实现跨设备冥想会话日志。Apple TV或Mac上完成的会话应同步到iPhone,以便记录到HealthKit。
agent产出的内容:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ tvOS │ │ Mac │ │ Watch │
│ TVTimerMgr │ │ TimerMgr │ │ WatchTimer │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────┼───────────────────┘
│
▼
┌────────────────────────┐
│ SessionStore │
│ (iCloud Key-Value) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ iPhone (on foreground)│
│ → Write to HealthKit │
└────────────────────────┘
agent:
1. 创建了MeditationSession数据模型,包含UUID、日期、时长、来源设备和HealthKit同步状态
2. 构建了SessionStore单例,使用NSUbiquitousKeyValueStore管理iCloud同步
3. 实现合并冲突解决(基于UUID去重)
4. 添加SessionHistoryView,包含平台特定适配(iOS上滑动删除,tvOS上基于焦点)
5. 连接iPhone端HealthKit同步,用于同步来自其他设备的会话
需要迭代的地方:初始实现没有处理iPhone应用在后台启动的情况(没有用于同步的前台通知)。agent需要明确提示:“Use NSUbiquitousKeyValueStore.didChangeExternallyNotification to trigger sync on background KV changes.”得到这个提示后,实现就是正确的。
经验教训:当架构描述清晰时,agent能够很好地处理多平台架构模式。iCloud同步模式并不简单,但它遵循有文档可依的Apple模式,agent能够理解。边缘情况(后台同步)需要人的领域知识,因为它的文档并不充分。
案例研究5:Starfield Destroyer中的Game Center集成(成功)
任务:为空间射击游戏添加Game Center排行榜和成就。
agent做得好的地方:
- 在应用入口点实现GKLocalPlayer.local.authenticateHandler
- 创建GameCenterManager,包含分数提交和成就上报方法
- 在所有Game Center操作前添加认证状态检查
- 优雅处理离线情况(游戏可在没有Game Center时运行,重新连接后提交)
- 创建与8艘飞船进度系统匹配的成就定义
需要手动完成的工作: - 在App Store Connect中创建排行榜和成就(网页门户,agent无法访问) - 在Xcode中配置Game Center entitlement - 使用沙盒Game Center账号测试(需要在设备上手动登录)
使用 Agents 的项目生命周期
启动新的 iOS 项目
在 Agent 辅助下启动新项目的最佳工作流:
阶段 1:人工设置(15-30 分钟) 1. 创建 Xcode 项目(File > New > Project) 2. 配置签名和功能 3. 设置部署目标和支持的目标设备 4. 添加所有必需的 entitlements(HealthKit、Game Center 等) 5. 创建初始 CLAUDE.md,写明项目身份和规则
阶段 2:Agent 实现(数小时到数天) 1. Agent 创建数据模型(SwiftData、Core Data 或普通 structs) 2. Agent 按照您记录的模式构建视图 3. Agent 在 manager/service 类中实现业务逻辑 4. Agent 编写单元测试 5. 通过 MCP 执行构建-测试-修复循环(自主)
阶段 3:人工集成(30-60 分钟) 1. 将 Agent 创建的文件添加到 Xcode targets 2. 验证签名和 entitlements 3. 在实体设备上测试 4. 审查视觉布局和 UX 5. 提交到 App Store Connect
维护现有项目
对于成熟应用的持续开发:
You: Here's the next feature for Return: add a "Focus Score" that
calculates from session duration and consistency. Show it on
the main timer view. Build and test.
Claude: [reads CLAUDE.md, understands patterns]
[reads TimerManager.swift, Settings.swift]
[creates FocusScore.swift — model with calculation logic]
[creates FocusScoreView.swift — display component]
[integrates into ContentView.swift]
[calls build_sim — 1 error: missing import]
[fixes import]
[calls build_sim — success]
[writes FocusScoreTests.swift]
[calls test_sim — all pass]
Agent 的效果取决于 CLAUDE.md 对项目当前状态的反映程度。添加重要新功能、改变架构模式或引入新 frameworks 时,请更新 CLAUDE.md。
何时让 Agent 参与,何时不应参与
| 任务 | Agent? | 原因 |
|---|---|---|
| 新 SwiftUI view | 是 | Agents 擅长声明式 UI |
| SwiftData model 变更 | 是 | 定义明确、可测试 |
| 单元测试 | 是 | 机械化、基于模式 |
| 重构 | 是 | 系统化、多文件 |
| 构建错误诊断 | 是(通过 MCP) | 结构化反馈循环 |
| 新 Xcode target | 否 | 需要 Xcode UI 和 .pbxproj 变更 |
| 签名和 provisioning | 否 | 基于门户,Agent 无法访问 |
| 视觉润色 | 否 | 需要人工审美判断 |
| Metal 着色器调优 | 否 | 需要在设备上进行 GPU 测试 |
| App Store 提交 | 否 | 需要门户和 Xcode Organizer |
| 性能剖析 | 否 | 需要 Instruments |
| 无障碍审计 | 部分 | Agent 可以添加 labels,人工验证 VoiceOver |
配置 Agent 定义
如果使用 Claude Code 的 Agent 定义系统(.claude/agents/),请创建一个 iOS 专用 Agent:
---
name: ios-developer
description: iOS development agent with MCP build tools and SwiftUI expertise
tools:
- XcodeBuildMCP
- xcode
---
# iOS Developer Agent
You are an iOS development agent for apps targeting iOS 26+ with SwiftUI.
## Architecture Rules
- @Observable for all view models (NEVER ObservableObject)
- NavigationStack for all navigation (NEVER NavigationView)
- SwiftData for persistence
- Swift 6.2 strict concurrency
- @MainActor on all Observable classes
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim`
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
MCP returns structured JSON. Bash returns unstructured text.
## File Management Rules
- NEVER modify .pbxproj, .xcodeproj/, .xcworkspace/, .xib, .storyboard
- Create Swift files in the correct directory
- Report files that need manual addition to Xcode targets
## SwiftData Rules
- @Model classes are automatically Observable — do not add @Observable
- Use @Bindable for form bindings to model properties
- Use @Query in views, modelContext.fetch() elsewhere
- Document relationship delete rules
## When You Get Stuck
- Build errors: use `build_sim` via MCP for structured output
- API questions: use `DocumentationSearch` via Apple MCP
- Swift verification: use `ExecuteSnippet` via Apple MCP
- Never guess — verify with tools
在 Claude Code 会话中使用 @ios-developer 引用此 Agent。
Agent 辅助 iOS 的测试模式
在获得清晰指导时,Agents 可以编写出色的单元测试。以下模式通常效果最佳。
测试文件组织
# In CLAUDE.md:
## Test Structure
Tests mirror source structure:
- `ReturnTests/TimerManagerTests.swift` tests `TimerManager.swift`
- `ReturnTests/SettingsTests.swift` tests `Settings.swift`
- `ReturnTests/ConstantsTests.swift` tests `Constants.swift`
Test naming: `test_<what>_<condition>_<expected>`
Example: `test_start_whenStopped_transitionsToRunning`
测试提示词
有效的测试提示词:
Write unit tests for TimerManager covering:
1. Initial state is .stopped with timeRemaining == selectedDuration
2. start() transitions state to .running
3. pause() from .running transitions to .paused
4. reset() from any state returns to .stopped with original duration
5. start() from .paused resumes (state becomes .running)
6. Edge case: reset() when already stopped is a no-op
7. Edge case: pause() when already paused is a no-op
Follow the existing test pattern in SettingsTests.swift.
Use setUp() to create a fresh TimerManager for each test.
为什么有效:编号式验收标准为 Agent 提供了清单。引用现有测试文件可以建立模式。指定 setUp() 用法能避免 Agent 创建纠缠不清的测试状态。
低效的测试提示词:
Write tests for TimerManager.
这会生成泛泛而浅层的测试,遗漏边界情况,并且可能不遵循项目模式。
Async 测试模式
针对基于 timer 和 async 的代码进行测试时:
// Agent produces this pattern when guided correctly:
final class TimerManagerTests: XCTestCase {
var sut: TimerManager!
@MainActor
override func setUp() {
super.setUp()
sut = TimerManager()
}
@MainActor
func test_start_whenStopped_transitionsToRunning() {
// Given
XCTAssertEqual(sut.state, .stopped)
// When
sut.start()
// Then
XCTAssertEqual(sut.state, .running)
}
@MainActor
func test_timerCountsDown_afterOneSecond() async throws {
// Given
sut.selectedDuration = 10
sut.reset()
sut.start()
// When
try await Task.sleep(for: .seconds(1.1))
// Then
XCTAssertLessThanOrEqual(sut.timeRemaining, 9.0)
}
}
需要提醒 Agents 的关键模式:
- 测试 @MainActor 类的测试方法需要标注 @MainActor
- 使用 Task.sleep 或 async 操作的测试需要 async throws
- 基于时间的断言应留有容差(1.1 秒,而不是严格 1.0)
- 使用干净的 setUp() / tearDown() 保持测试隔离
Snapshot Testing
对于视觉回归检测,可以考虑添加 swift-snapshot-testing:
Add snapshot tests for the main timer view in three states:
1. Stopped (showing full duration)
2. Running (showing countdown)
3. Completed (showing 00:00 with completion state)
Use SnapshotTesting library. Create reference images on first run.
Agents 可以正确设置 snapshot tests,但无法审查参考图像。您负责审查初始 snapshots,随后 Agent 的测试会在未来变更中捕获视觉回归。
iOS项目的上下文窗口管理
1M上下文窗口(Opus 4.6)很大,但并非无限。iOS项目有其特定的上下文管理注意事项。
iOS文件的Token成本
| 文件类型 | 典型大小 | 近似Token数 |
|---|---|---|
| SwiftUI视图(简单) | 50-100行 | 500-1,000 |
| SwiftUI视图(复杂) | 200-400行 | 2,000-4,000 |
| SwiftData模型 | 30-80行 | 300-800 |
| 管理器/服务类 | 100-300行 | 1,000-3,000 |
| Metal shader(.metal) | 50-200行 | 500-2,000 |
| 单元测试文件 | 50-200行 | 500-2,000 |
| CLAUDE.md | 100-300行 | 1,000-3,000 |
| MCP响应(构建) | 不定 | 200-2,000 |
| MCP响应(测试) | 不定 | 500-5,000 |
对于50个文件的项目:读取所有文件大约消耗50,000-100,000个Token,远低于1M窗口容量。代理可以将整个项目保留在上下文中。
对于100+个文件的项目:必须进行选择性读取。代理会先读取CLAUDE.md(获取文件结构注释),然后按需读取特定文件。这正是CLAUDE.md中的文件注释至关重要的原因:它们可以引导代理直接找到正确文件,而无需读取全部内容。
大型项目策略
- 详细的CLAUDE.md文件注释——代理读取文件映射,并直接导航到相关文件
- 子代理委派——将探索和研究交给子代理(干净上下文,返回摘要)
- 聚焦提示词——“Modify SettingsView.swift to add a new toggle”比“update the settings”更好
- 会话边界——为不相关功能启动新会话,而不是不断延长一个长会话
- 使用
/compact——Claude Code的压缩命令会总结对话并释放上下文
MCP的Token效率
支持MCP的最有力理由之一是:结构化的JSON响应比原始xcodebuild输出消耗少得多的Token。
| 场景 | 原始Bash Token | MCP Token | 节省 |
|---|---|---|---|
| 构建成功 | 3,000-10,000 | 200-500 | 85-95% |
| 构建失败(1个错误) | 3,000-10,000 | 300-800 | 90-92% |
| 测试结果(20个测试) | 2,000-5,000 | 500-1,000 | 75-80% |
| 模拟器列表 | 500-2,000 | 200-400 | 60-80% |
在一次包含10-20轮构建周期的典型开发会话中,相比原始xcodebuild,MCP可节省30,000-150,000个Token。这些Token可继续用于真正的代码推理。
故障排查
“build_sim failed — scheme not found”
代理正在猜测scheme名称。修复方法:
Use discover_projs and list_schemes to find the correct scheme name
for this project before building.
或者在CLAUDE.md中明确添加scheme名称:
## Build
Primary scheme: `Return` (iOS)
Watch scheme: `ReturnWatch` (watchOS)
TV scheme: `ReturnTV` (tvOS)
“xcrun mcpbridge — command not found”
需要Xcode 26.3或更高版本。使用xcodebuild -version检查。如果已经安装Xcode 26.3+,但命令仍然失败:
# Ensure Xcode command line tools are selected
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# Verify
xcrun mcpbridge --help
“MCP工具未出现在Claude Code中”
会话中途注册的MCP工具可能要到重启后才会出现。退出Claude Code并启动一个新会话:
# Exit current session (Ctrl+C or /exit)
# Start fresh
claude
然后验证:
You: List all available MCP tools from XcodeBuildMCP.
“代理一直通过Bash使用xcodebuild,而不是MCP”
代理没有通过Tool Search发现MCP工具。两种修复方式:
- 向CLAUDE.md添加明确指导(请参阅教会代理使用MCP)
- 直接提示:“Use the build_sim MCP tool, not xcodebuild via Bash”
“构建成功,但代理报告失败”
XcodeBuildMCP会解析xcodebuild输出。如果构建产生了看起来像错误的警告(弃用警告中很常见),代理可能会误判结果。请检查MCP响应中的实际状态字段。
“模拟器启动时卡住”
结束所有模拟器并重新启动:
xcrun simctl shutdown all
xcrun simctl boot "iPhone 16 Pro"
或者询问代理:
Shut down all simulators, then boot a fresh iPhone 16 Pro.
“代理不顾CLAUDE.md规则尝试修改.pbxproj”
CLAUDE.md规则是建议。Hooks才是强制执行。如果没有PreToolUse hook阻止对.pbxproj的写入,代理最终会尝试这样做。请安装hook:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files.\" >&2; exit 2; fi'"
}
]
}
}
规则是在说“请不要”。Hooks是在说“不能”。
常见问题
我应该从哪个 agent runtime 开始?
Claude Code CLI 与 XcodeBuildMCP 搭配使用。它拥有最深入的 MCP 集成、最成熟的 hook 系统,以及可将整个 iOS 项目保留在工作记忆中的 1M 上下文窗口(Opus 4.6)。建议从这里开始;随着工作流成熟,再加入 Codex 用于审查,并使用 Xcode native agents 进行快速 inline edits。
我需要同时使用两个 MCP 服务器吗?
对大多数开发者来说,仅 XcodeBuildMCP 就能覆盖 90% 的需求(构建、测试、模拟器、调试)。如果需要文档搜索、Swift REPL 验证或 SwiftUI preview 渲染,再添加 Apple 的 Xcode MCP。后续随时可以添加;这两个服务器彼此独立。
agents 能从零创建新的 Xcode 项目吗?
XcodeBuildMCP 包含一个 create_project 工具,可用于脚手架生成新的 Xcode 项目。不过,对于生产应用,我建议在 Xcode 中创建项目(以确保签名、capabilities 和 target 配置正确),然后使用 agents 完成所有代码实现。在 Xcode 新项目向导中花费的 5 分钟,可以节省数小时由 agent 生成项目配置所带来的问题。
agents 如何处理 Swift Package Manager 依赖?
处理得很好。Package.swift 是标准 Swift 文件,agents 可以可靠地读取和编辑。添加依赖、更新版本范围以及配置 targets 都能正常完成。限制在于基于 .xcodeproj 的依赖管理(Xcode 的 package resolution UI);这由 Xcode 管理,不应交由 agent 编辑。
agents 能提交到 App Store 吗?
不能。App Store 提交涉及 Xcode 的 Organizer、provisioning profiles、截图、元数据以及 App Store Connect 门户。这些内容无法通过 MCP 或命令行工具以 agents 可有效操作的方式访问。agents 可以处理归档之前的所有工作,包括实现、测试、修复 bug 和文档。提交的最后一公里仍需人工完成。
不过,agents 可以协助处理 App Store 元数据。可以让 agent 根据最新变更编写应用描述、关键词和 what’s-new 文案。这类文本生成工作正是 agents 的强项。
在 agent 辅助的 iOS 开发中,如何处理 secrets 和 API keys?
绝不要提交 secrets。对于连接后端 APIs 的 iOS 应用:
- 使用
.xcconfig文件管理特定环境的配置 - 将
.xcconfig文件加入.gitignore - 通过
Info.plistbuild settings 引用配置值 - 在 CLAUDE.md 中记录所需 secrets,但不要包含实际值
## Configuration
API base URL and keys are in `Config.xcconfig` (not committed).
Required keys:
- `API_BASE_URL` — Backend server URL
- `API_KEY` — Authentication token
Create `Config.xcconfig` from `Config.xcconfig.template`.
agent 知道这些 keys 存在以及它们在哪里使用,但永远看不到实际值。
SwiftUI 动画呢?agents 能写吗?
agents 在语法层面能很好地编写动画代码,但无法通过视觉方式验证结果。简单动画(.animation(.spring())、.transition(.slide)、withAnimation { })通常能得到正确结果。复杂、多步骤且需要精确时序的动画,则需要视觉迭代,而 agents 无法完成这一点。
有效:“在计时器状态切换时添加 spring animation。”
无效:“让计时器动画感觉更令人满意。”(主观判断,需要视觉调优。)
agents 如何处理错误处理模式?
处理得很好。agents 理解 Swift 的 do/catch、Result 和 async throws 模式:
Implement error handling for the HealthKit authorization flow:
1. Check HKHealthStore.isHealthDataAvailable() — show alert if not
2. Request authorization — handle denial gracefully
3. On write failure — retry once, then show error
4. All errors should be user-facing with localized descriptions
agents 会生成结构化的错误处理,并提供合适的面向用户消息。它们有时会过度处理错误(捕获本应继续向上传播的异常),因此需要审查 catch blocks。
我可以使用 agents 实现 accessibility 吗?
可以部分实现。agents 能正确添加 accessibility labels、hints 和 traits:
Add accessibility labels to all interactive elements in TimerView:
- Timer display: current time remaining
- Start/Pause button: current state and action
- Reset button: "Reset timer"
- Duration picker: selected duration
agents 无法做到的是:验证 VoiceOver 导航顺序是否正确、测试 Dynamic Type 缩放,或评估颜色对比度。请使用 Xcode 的 Accessibility Inspector 进行验证。
agents 如何处理 Core Data migration(如果不使用 SwiftData)?
agents 可以编写 Core Data migration mappings 和 model versions,但手动 Xcode 步骤(创建新的 model versions、选择当前版本)无法自动化。如果您仍在使用 Core Data 而不是 SwiftData,请在 CLAUDE.md 中记录 model version 历史:
## Core Data Model Versions
- V1: Initial (GroceryList, GroceryItem)
- V2: Added Category model (current)
- Migration: Lightweight automatic for V1→V2
agents 如何处理 SwiftUI previews?
有两种方式:
1. Apple Xcode MCP 的 RenderPreview 工具可无头渲染 previews 并返回结果。agent 可以验证 preview 是否能编译并无错误渲染,但无法评估视觉正确性。
2. 基于构建的验证通过 build_sim 确认 preview providers 能否编译。如果 preview 在运行时崩溃,构建仍会成功;崩溃只会在 Xcode 尝试渲染 preview 时出现。
如需对 previews 进行视觉验证,仍然需要打开 Xcode。
visionOS 和 Apple Vision Pro 呢?
同样的模式适用。XcodeBuildMCP 支持 visionOS 模拟器,架构模式(@Observable、NavigationStack、SwiftData)也完全相同。RealityKit 相关代码(3D 内容、immersive spaces、hand tracking)遵循与 Metal 相同的限制:agents 可以编写正确代码,但无法验证空间输出。
项目大到什么程度后 agents 会吃力?
上下文窗口大小是限制因素。借助 Opus 4.6 的 1M token 窗口,Claude Code 可以同时将约 50-70 个 Swift 文件保留在活跃工作记忆中。对于更大的项目,agent 会使用文件搜索和选择性读取来处理代码库子集。100+ 文件的项目也能正常工作;agent 只是按需读取文件,而不是把所有内容都放入上下文。
实际限制不是文件数量,而是代码库的连贯性。一个文档完善、包含详细 CLAUDE.md 的 200 文件项目,会比一个缺少文档的 30 文件项目产生更好的结果。
我需要懂 Swift 才能用 agents 做 iOS 开发吗?
您需要能够审查 agent 输出并做出架构决策。不必亲自编写每一行代码,但需要足够理解 Swift,才能发现 agent 做出错误选择的情况,尤其是在并发、内存管理和特定框架模式方面。agent 是对现有技能的 10 倍放大器,而不是替代品。
agents 如何处理 Swift 文件中的 merge conflicts?
agents 能可靠地解决 Swift 源文件中的 merge conflicts。所有 agent runtime 都能很好理解标准冲突标记(<<<<<<<、=======、>>>>>>>)。不过,.pbxproj 文件中的 merge conflicts 仍然需要手动解决;不要要求 agents 解决 .pbxproj conflicts。
运行 agents 进行 iOS 开发的成本是多少?
使用 Anthropic 的 Max plan(Opus 4.6,1M 上下文)时,一次典型 iOS 开发会话持续 30-120 分钟,处理 200K-800K tokens。MCP tool calls 只会增加极少开销(与原始构建输出相比,结构化 JSON responses 更节省 tokens)。成本与在其他代码库上运行 Claude Code 相当;iOS 开发并不明显比 Web 开发更贵或更便宜。
我可以在 UIKit 项目中使用 agents 吗?
可以,但 agents 在 SwiftUI 中更有效。UIKit 需要更多样板代码,声明式结构更少,并且经常涉及 agents 无法编辑的 Interface Builder 文件。如果有 UIKit 项目,可以考虑让 agents 处理 model layer 和业务逻辑,同时手动处理 UI;也可以逐步将 views 迁移到 SwiftUI。
agents 如何处理 localization?
agents 能有效创建和编辑 .xcstrings(Xcode string catalog)文件。它们可以添加新的 localization keys、提供翻译,并维护跨语言一致性。.xcstrings 文件的结构化 JSON 格式对 agents 很友好。对于 .strings 文件(旧格式),agents 同样表现良好;key-value 格式清晰直接。
iOS中的常见Agent错误(以及如何预防)
这些是我在8个iOS项目、数千次agent交互中反复观察到的错误。每个错误都有对应的预防策略。
错误1:混用Observable模式
发生了什么:agent在一个文件中使用@Observable,在另一个文件中使用ObservableObject,或者把@Observable添加到@Model类上(而@Model本身已经是Observable)。
预防:在CLAUDE.md中写明规则:
- NEVER use ObservableObject — use @Observable
- NEVER add @Observable to @Model classes (already Observable)
- NEVER use @StateObject — use @State with @Observable
- NEVER use @ObservedObject — access @Observable properties directly
错误2:在闭包中造成retain cycle
发生了什么:agent创建了强引用捕获self的闭包,尤其常见于Timer.publish、NotificationCenter和completion handler。
预防:在CLAUDE.md中加入闭包模式:
## Closure Pattern
- Timer callbacks: use `[weak self]` and guard
- NotificationCenter observers: store in `Set<AnyCancellable>` and use `[weak self]`
- Completion handlers: use `[weak self]` for any closure stored beyond the call site
错误3:忽略@MainActor要求
发生了什么:agent创建@Observable类时没有使用@MainActor隔离,导致Swift 6.2并发警告,或在UI更新发生于主线程之外时引发运行时崩溃。
预防:
## Concurrency Rule
ALL @Observable classes MUST be @MainActor:
```swift
@Observable
@MainActor
final class SomeManager { }
```
错误4:使用带destination闭包的NavigationLink
发生了什么:agent使用已废弃的NavigationLink(destination:label:),而不是类型安全的NavigationLink(value:) + .navigationDestination(for:)模式。
预防:
## Navigation Pattern
ALWAYS use value-based navigation:
```swift
NavigationLink(value: item) { ItemRow(item: item) }
.navigationDestination(for: Item.self) { ItemDetailView(item: $0) }
```
NEVER use: `NavigationLink(destination: ItemDetailView(item: item)) { }`
错误5:硬编码模拟器名称
发生了什么:agent编写构建命令时使用特定模拟器名称(“iPhone 16 Pro”),而该模拟器在您的系统中可能并不存在。
预防:MCP会处理这一点——list_sims会发现可用的模拟器。在CLAUDE.md中:
## Simulators
Do NOT hardcode simulator names. Use `list_sims` MCP tool to discover
available devices, then `boot_sim` with the discovered device ID.
错误6:在错误目录中创建文件
发生了什么:agent把新的view文件创建在项目根目录,而不是Views/子目录中,或者把model放进了错误的group。
预防:CLAUDE.md中的文件结构注释会指导放置位置。此外:
## File Placement Rules
- Views → `AppName/Views/`
- Models → `AppName/Models/`
- Managers → `AppName/Managers/`
- Extensions → `AppName/Extensions/`
- Tests → `AppNameTests/`
错误7:未处理平台可用性
发生了什么:agent在会为tvOS编译的共享代码中使用HealthKit(tvOS不可用),或者在watchOS代码中使用ActivityKit。
预防:
## Platform Guards
- HealthKit: `#if canImport(HealthKit)` (unavailable on tvOS)
- ActivityKit: `#if canImport(ActivityKit)` (iOS only)
- WatchKit: `#if os(watchOS)`
- UIKit haptics: `#if os(iOS)` (unavailable on tvOS, watchOS uses WKHaptic)
错误8:把简单功能过度工程化
发生了什么:agent为一个本应是20行工具函数的功能创建了protocol、protocol extension、具体实现、factory和dependency injection container。
预防:加入简洁性原则:
## Architecture Principle
Prefer the simplest solution that handles the requirements.
- Direct implementation over protocol abstraction (unless you have 2+ conforming types)
- Concrete types over generics (unless reuse is proven)
- Extensions on existing types over new wrapper types
坦诚评估
在用AI agents发布8个iOS应用之后,总结如下:
Agents改变了:实现速度。过去需要数天的工作,现在数小时即可完成。SwiftUI views、SwiftData models、unit tests、refactoring——这些现在主要由agent生成,再由人来review。
Agents没有改变:架构决策、视觉设计、性能优化或App Store提交。这些仍然由人主导。
倍增效应真实存在,但有边界。我对这8个应用组合的主观估计是:在文档完善、MCP和hook配置得当的项目中,time-to-feature提升约3-5倍。这不是与对照组的测量结果;而是在同一批代码库中,将agent辅助功能开发与等价的个人独立开发进行wall-clock对比。没有文档、没有hooks的项目可能只有1.5-2倍提升——agent会花太多时间猜测,而不是构建。19
真正值得投入的是:花在CLAUDE.md、hooks和MCP配置上的时间。每投入1小时设置,都会节省许多小时用于纠正agent错误。配置本身就是产品——agent只是执行引擎。
让我意外的是:MCP servers在很大程度上改变了协作动态。在MCP之前,agents只是碰巧懂Swift的高级文本编辑器。在MCP之后,它们成了能够编写、构建、测试、调试和迭代的开发伙伴。结构化反馈循环,正是只会写代码的agent与能够交付代码的agent之间的关键差异。
我会告诉过去的自己:从最小的应用开始(Reps,14个文件),先把MCP和hook设置做好,写一份详尽的CLAUDE.md,然后再把这些模式扩展到更大的项目。不要一开始就做那个63个文件的多平台应用。无论项目大小,基础设施投入都是一样的——先在小项目中做好一次,然后复制到其他所有项目。
未来:Xcode 26.3的原生agent集成只是开始,而不是终点。Apple推出MCP支持,意味着toolchain正在走向agent-first开发。现在投资agent-compatible项目结构的开发者——清晰的CLAUDE.md文件、可测试架构、自动化hooks——会随着工具改进而持续复利。
快速参考卡
安装(一次性设置)
# XcodeBuildMCP (59 tools)
claude mcp add XcodeBuildMCP -s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Apple Xcode MCP (20 tools)
claude mcp add --transport stdio xcode -s user -- xcrun mcpbridge
# Codex MCP setup
codex mcp add xcode -- xcrun mcpbridge
# Verify
claude mcp list
CLAUDE.md核心章节
1. Project identity (bundle ID, target OS, architecture)
2. File structure with annotations
3. Build and test commands
4. Key patterns and rules
5. Prohibitions (NEVER touch .pbxproj)
6. Framework-specific context
核心Hooks
{
"PreToolUse": [{ "matcher": "Edit|Write", "command": "block .pbxproj" }],
"PostToolUse": [{ "matcher": "Edit|Write", "command": "swiftformat" }]
}
架构规则
@Observable (not ObservableObject)
NavigationStack (not NavigationView)
@State (not @StateObject)
SwiftData @Model (not Core Data)
async/await (not completion handlers)
@MainActor (on all Observable classes)
.glassEffect() (Liquid Glass, iOS 26+)
MCP工具优先级
Build: build_sim (not xcodebuild via Bash)
Test: test_sim (not xcodebuild test via Bash)
Sim: list_sims/boot_sim (not xcrun simctl via Bash)
Docs: DocumentationSearch (not WebSearch)
REPL: ExecuteSnippet (not swift via Bash)
更新日志
| 日期 | 变更 |
|---|---|
| 2026-05-24 | 将 Xcode 26.5 稳定版发布日期更正为 2026-05-11,并根据 Apple 发布页面将构建版本固定为 17F42。本轮本地验证:xcodebuild -version 返回 Xcode 26.5 / Build version 17F42;xcodebuildmcp 的 npm latest 返回 2.5.2,time.modified 为 2026-05-12T07:40:41.737Z。13 |
| 2026-05-16 | 将推荐的 Xcode 提升至 26.5+(发布于 2026-05-11)。两个新的 Coding Intelligence 功能对 agent 工作流很重要:现在可以在 coding assistant 中排队发送消息,因此无需等待回复完成即可安排下一条请求;agent 也可以在继续之前提出澄清问题。这两项都降低了将 Xcode 原生 agent 与 Claude Code 或 Codex 会话并行运行的摩擦。13 XcodeBuildMCP 时效性检查:v2.5.2(2026-05-12)为最新版本,新增捆绑的 AXe 1.7.0,并修复了日志捕获过滤器验证问题;v2.1.0+ 起的 xcodebuildmcp init 流程仍是推荐安装路径。 |
| 2026-04-28 | 将 agent 工作流推荐的 Xcode 提升至 26.4+(26.4.1,2026-04-16,build 17E202 是最新稳定版,仅包含错误修复)。引用了对 agent 编写测试和本地化有用的 Xcode 26.4 功能(2026-03-24,build 17E192):Swift Testing 图像附件、Issue.record 的严重级别、带附加 crashlog 的 UI 测试崩溃警告(专门适用于 XCUIApplication(bundleIdentifier:) / XCUIApplication(url:) 应用)、String Catalog 编辑器改进。添加了 xcodebuildmcp init 自动安装器(v2.1.0+,2026-02-23),作为手动设置 MCP 的替代方案。 |
| 2026-04-27 | App Store Connect:自 2026-04-28 起,提交必须使用 Xcode 26+ 构建。Foundation Models 新增 SystemLanguageModel.contextSize 和 tokenCount(for:) API(向后部署至 iOS 26.4),因此添加了 agent 生成 FM prompt 预算代码的模式。iOS 26.4.2(4月22日)和 iOS 26.5 beta 3(4月20日)发布时没有影响 agent 工具链的变更。 |
| 2026-04-13 | 首次发布。8 个应用、3 个运行时、MCP 设置、CLAUDE.md 模式、hooks、案例研究。 |
参考资料
-
XcodeBuildMCP 默认包含 Sentry 遥测。该项目的隐私文档详细说明了会发送哪些内容:错误消息、堆栈跟踪,以及在某些情况下的文件路径。
XCODEBUILDMCP_SENTRY_DISABLED=true环境变量可完全退出遥测。 ↩ -
Anthropic,“Model Context Protocol Specification”,modelcontextprotocol.io/specification。MCP 规范定义了 XcodeBuildMCP 和 Apple 的 Xcode MCP 都实现的 JSON-RPC 传输、工具发现和资源协议。 ↩
-
XcodeBuildMCP,github.com/getsentry/XcodeBuildMCP。开源,由 Sentry 维护。涵盖 simulator、device、debugging 和 UI automation 工作流的 59 个工具。采用语义化版本控制,并提供更新日志。 ↩
-
Apple 将 Xcode MCP server 作为 Xcode 26.3 智能开发者工具计划的一部分推出,并将 MCP 定位为 AI coding assistants 与 Xcode 工具链之间的接口层。官方文档请参阅 Xcode Release Notes。 ↩
-
Rudrank Riyam,“Exploring Xcode Using MCP Tools”,rudrank.com/exploring-xcode-using-mcp-tools-cursor-external-clients,2026。独立确认了 Apple 的 MCP 工具数量、XPC 依赖以及文档搜索能力。 ↩
-
Jimenez, C.E., Yang, J., Wettig, A., et al.,“SWE-bench: Can Language Models Resolve Real-World GitHub Issues?” ICLR 2024。arxiv.org/abs/2310.06770。拥有结构化工具访问能力的 agent 明显优于仅限非结构化 shell 命令的 agent。该发现验证了结构化 MCP 接口对 agent 有效性的价值。 ↩
-
Claude Code CLI 文档,code.claude.com。Hook 系统、MCP 配置、subagent 委派和 agent 定义。 ↩
-
SwiftFormat,github.com/nicklockwood/SwiftFormat。用于 PostToolUse hooks 的 Swift 格式化工具,以保持一致的代码风格。 ↩
-
XcodeBuildMCP 官方网站,xcodebuildmcp.com。通过 CLI 输出示例确认 59 个 MCP 工具。工具类别:simulator、device、debugging 和 UI automation。可通过 Homebrew 或 npx 安装。 ↩
-
Swiftjective-C,“Agentic Coding in Xcode 26.3 with Claude Code and Codex”,swiftjectivec.com,2026年2月。确认 Xcode 26.3 通过 Settings > Intelligence 随附原生 Claude Agent,并支持 Codex 运行时。通过
xcrun mcpbridge暴露 20 个 MCP 工具。 ↩ -
Blake Crosley,“Two MCP Servers Made Claude Code an iOS Build System”,blakecrosley.com/blog/xcode-mcp-claude-code,2026年2月。来自同一作者 iOS 开发工作流的设置 walkthrough 和真实结果。 ↩
-
Apple Developer News,“Upcoming Requirements”。2026-04-28 条目:“Apps uploaded to App Store Connect must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26, or watchOS 26.” macOS 不在此要求列出的平台集合中。 ↩
-
Apple,“Xcode 26.5 Release Notes” 和 “Xcode 26.5 (17F42) - Releases”。Apple 于 2026-05-11 列出 Xcode 26.5,构建版本为 17F42。引用自发布说明的两个 Coding Intelligence 功能:可以在 coding assistant 中排队消息,而无需等待当前回复完成(174563016);agent 可以提出澄清问题,以在继续之前收集上下文(175182375)。还包括对 12 个月承诺月付订阅的 StoreKit Testing 支持(
PricingTerms模型、billingPlanTypePurchaseOption、Transaction和SubscriptionRenewalInfo上的CommitmentInfo),以及针对 Swift Tasks 在 async/await 操作期间迁移线程时逐步调试的 Swift debugger 修复。2026-05-24 当前会话验证:xcodebuild -version返回Xcode 26.5和Build version 17F42;npm view xcodebuildmcp version dist-tags.latest time.modified --json返回 latest2.5.2,time.modified为2026-05-12T07:40:41.737Z。另见:9to5Mac,“Xcode 26.5 adds two features that make agentic coding more useful”,2026-05-12。 ↩↩↩ -
Apple,“Xcode 26.4 Release Notes”。Xcode 26.4(2026-03-24,build 17E192)。引用自发布说明的功能:Swift Testing 现在支持通过
CGImage、NSImage、UIImage和CIImage添加图像附件;Issue.record接受严重级别;某些 UI 测试应用崩溃,具体而言是通过XCUIApplication(bundleIdentifier:)或XCUIApplication(url:)交互的应用,会以附带 crashlog 的警告形式报告,而不是让测试失败;String Catalog 编辑器新增条目的剪切/复制/粘贴、语言移除、从现有语言预填翻译,以及BUILD_ONLY_KNOWN_LOCALIZATIONS设置。 ↩ -
Apple Developer News,“Xcode 26.4.1 (Build 17E202) Now Available”,2026-04-16。仅错误修复的小版本发布:修复了 iOS / macOS / visionOS 26.4 之前版本上因缺少符号导致的 MetricKit 崩溃,以及 Swift async 栈分配错误(
swift_asyncLet_finish中的 “freed pointer was not the last allocation”)。 ↩ -
getsentry/XcodeBuildMCP v2.1.0 release,2026-02-23。新增
xcodebuildmcp initCLI 命令,可一步安装 agent skills + MCP 配置,取代独立的install-skill.sh脚本。自动检测 Claude Code、Cursor 和 Codex;支持--print(将配置写入 stdout,供不受支持的客户端使用)和--uninstall(移除)。 ↩ -
InfoQ,“Apple Adds Context Window Management to Foundation Models”,2026年3月。记录了新的
SystemLanguageModel.contextSize和tokenCount(for:)API,并确认@backDeployed(before: iOS 26.4)注解。取代了此前社区对 4096-token 硬编码的猜测。 ↩ -
文件数量来自 2026-04-27 对 8 个私有应用仓库分别运行
find . -name '*.swift' -not -path '*/Tests/*' | wc -l的结果。测试文件已排除。总数与 §The Portfolio 中按应用拆分的表格保持内部一致。 ↩ -
主观的墙钟时间估算,不是与对照组进行的测量。3-5x 这一数字来自作者对 2026 年 agent 辅助功能与同一代码库中 agent 工作流之前独立交付的等效功能之间 time-to-feature 对比的回忆。应将其视为完成 MCP + hook 设置后可期待效果的启发式参考,而不是基准测试。 ↩