当前位置:首页>iOSAPP>苦尽甘来:在现有 iOS 项目中落地 Spec-Kit 的实战指南

苦尽甘来:在现有 iOS 项目中落地 Spec-Kit 的实战指南

  • 2026-11-09 01:07:49
苦尽甘来:在现有 iOS 项目中落地 Spec-Kit 的实战指南

背景故事

QuGame(简称 “Qu”)是一款具备 Game Center 在线对战功能的 iOS 棋牌/拼图游戏。它的底子很厚:SwiftUI 撸的界面,核心引擎是一个本地 Swift Package(QuGameModel),还用了 Swift Macros。除了一个用来搞定 GameKit 匹配的“老古董” Objective-C 文件(MatchmakerDelegate.m),整个项目清一色全是 Swift。

这可不是什么从零开始的 Demo,而是一个开发已久的成熟项目。也就是说,我们这次是要在既有项目(Brownfield)中“硬拓” Spec-Kit,而不是在白纸上画画。

Spec-Kit 是 GitHub 出品的规范驱动开发(Spec-Driven Development, SDD)工具包。它把传统流程反过来了:不再是先写代码后补文档,而是先写出极其详尽的“规格说明书(Spec)”,然后让 AI 照着说明书去生成实现代码。

我想通过这篇文章,一步步记录下在真实项目里落地 Spec-Kit 到底是个什么体验。我原本抱有极高的期望……咱们往下看。

第一步:给 AI 装上“透视眼”(配置 Swift 分析 MCP 服务)

在折腾 Spec-Kit 之前,我们得先给 AI 助手的“大脑”升个级,让它能看懂复杂的 Swift 代码库。我们添加了一个 Model Context Protocol (MCP) 服务——简单说,就是一个 Swift 语义分析工具。它能解析 Swift 源码,吐出结构化的声明、导入和类型信息。

1a:配置 MCP 服务

我让 Claude Code 帮我搞定了这套配置。这个 MCP 服务住在 /Users/work/Documents/swiftMCP,它利用 Swift 解析器提取 .swift 文件的语义信息(类型、成员、访问权限、协议遵从等),并通过 MCP 协议暴露给 AI 工具。

1b:搓一个斜杠命令(Slash Command)

为了用起来爽,我让 Claude Code 建立了一个斜杠命令。这就是 AI 助手的魅力:你不需要手动改配置,直接吩咐它:“帮我连上线”。 现在,我只要在 Claude Code 里敲 /summarize-swift @QuGame/GamePlay/BagView.swift,它就能给我一份清爽的结构化报告——导入了啥、结构体长啥样、有哪些私有属性,全是基于 AST(抽象语法树)解析出来的,比纯文本盲猜准得多。

1c:初试牛刀

我们在 BagView.swift 上试了试,效果拔群。不过说实话……后面我发现 Spec-Kit 压根没怎么用到这个 MCP。所以,这步你要是想偷懒,跳过也行。

第二步:摸底——Spec-Kit 到底是个啥?

安装之前,我先去它的 GitHub 仓库调研了一下。

核心考点:

  • 命令行工具:Python 写的,用 uv(快到飞起的 Python 包管理器)安装。
  • 语言无关:它不管你是 Swift 还是 ObjC。Spec 描述的是“做什么”和“为什么”,而不是“怎么写”。
  • AI 深度集成:天生就是给 Claude、Copilot、Cursor 准备的。我们这里用 Claude Code。
  • 七步法流程:宪法(Constitution)→ 规范(Specify)→ 澄清(Clarify)→ 计划(Plan)→ 任务(Tasks)→ 验证(Validate)→ 实现(Implement)。
  • 对旧项目友好:它明确支持给老代码补 Spec。

第三步:安装 Spec-Kit

只要你有 Python 3.11+ 和 uv,一行命令搞定:

uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@v0.6.1

小贴士:如果装完提示找不到 specify 命令,记得把 ~/.local/bin 加到你的 PATH 环境里。

项目初始化

在项目根目录运行:

specify init . --ai claude

这是一个交互式命令。我建议你自己手跑,而不是让 AI 代劳,这样你能更清晰地掌控配置细节。

初始化后会生成:

  • .specify/:工具的“大脑”,放模板、脚本和记忆。
  • .claude/skills/:给 Claude Code 注入的超能力(斜杠命令)。

第四步:制定“宪法”——这是重中之重!

宪法(Constitution)是 SDD 流程的基石。所有的 Spec、计划和任务都要对着宪法“宣誓”。这步要是糊弄,整个框架就没牙了。

这玩意儿不是 README,也不是代码风格指南。它是一份有版本号的治理文档——是项目的原则底线。

我们的实战经验

我先让 Claude Code 去“巡视”了一圈代码库,做了两件事:

  1. 研读模板:搞清楚宪法该长啥样。
  2. 代码审计:看现在的 QuGame 到底是按什么套路写的(文件组织、测试方案、工程结构)。

翻车现场:第一版草案回来时,AI 自信满满地把项目描述成了“Swift 和 ObjC 混合项目”,还说核心引擎是“遗留的 ObjC”。破案了: AI 偷懒读了过时的 CLAUDE.md 文档。实际上 ObjC 引擎早就被我重写成 Swift 了。

教训:AI 极度迷信你的旧文档。如果文档是馊的,宪法就是歪的。我赶紧下令:“重新查数!只看现在的代码,不要信旧文档,给我肉眼去 ls 和 grep!”

最终定稿的五大原则

原则
核心规则
I. Swift 6 & iOS 17+ 适配
强制使用 @Observable、async/await、DocC 注释、swift-format。
II. 只准用 Swift Testing (不可动摇)
必须 import Testing,用 @Test 和 #expect。严禁 XCTest!
III. DRY 与简洁
禁止重复代码,YAGNI(你以后才用不到它),只在系统边界做校验。
IV. 状态驱动架构
只用原生的 @State、@Binding,不搞 MVVM,逻辑写在 Observable 类型里。
V. 关注点分离
Extension 必须分文件,新 View 必须自带 #Preview,改项目文件要守规矩。

运行宪法技能

万事俱备,召唤:

/speckit-constitution

运行完后,记得重启 Claude Code 进程,不然它认不出新安装的技能。

第五步:写下第一份 Spec —— /speckit-specify

终于要动真格的了。

为什么选“排行榜领奖台”功能?

这个功能原本就有,但 Bug 满天飞,交互也得重做。在老功能上写 Spec 是个极好的测试:如果不从零开始,Spec-Kit 还灵吗?

我是怎么“画饼”的

我压根没提现有的烂代码,直接描述我想要的:

“

“用户每天第一次启动,弹个领奖台。前三名排排坐,还要显示用户的连胜纪录。背景静默刷新数据,如果排名变了,领奖台要自动刷新并带动画。升职了撒花(Confetti),降级了也要有醒目的提醒。领奖台要像奥运会那样:金银铜,底座高度要跟分数挂钩。展示 5-7 秒后自动消失。”

奇迹时刻

命令一敲,Git 钩子自动生效:

  1. 自动拉了个新分支 001-daily-ranking-podium。
  2. 创建了目录 specs/001-daily-ranking-podium/。
  3. 把我的口语拆解成了:3 个用户故事、15 个功能要求、6 个边界情况。
  4. 最关键的是:我完全没解释现有的代码。让 AI 在下一步(计划)里自己去考古。

第六步:澄清 —— /speckit-clarify

在动手之前,AI 会过来确认细节(最多问 5 个问题)。 它问了:

  • “排名变化”是指名次变了还是分数变了?(答:名次)。
  • 打游戏时突然弹窗合适吗?(答:游戏时禁弹)。
  • 本地玩家如果在前三名,要不要加特效?(答:加个光晕)。

第七步:做计划 —— /speckit-plan

这是 AI 第一次正儿八经读你的代码。它派出了“研究特工”去扫描我的排行榜系统、头像组件和庆祝动画。

旧项目改造的福音:AI 回复我:“太棒了,研究发现大部分组件(ConfettiView、RankService 等)都已经有了。我们只需要做针对性的增强,不用推倒重来。”

它生成了详细的 plan.md,甚至做了一份状态迁移图。最牛的是,它会拿着计划去对撞“宪法”:“报告,本方案符合 Swift 6 规范,且没有使用 XCTest,准予执行!”

第八步:开搞 —— /speckit-implement

顺风局

基础工作很扎实:建立了 RankSnapshot 模型,增强了现有的 View,修好了一些无关痛痒的并发错误。编译一次过,零报错。

逆风局(大型翻车现场)

领奖台的主视图 DailySpotlightView 居然重写了好几遍。病根:AI 习惯性把简单问题复杂化。Spec 说:显示昨天的排名 → 等待 → 显示今天的排名 → 做过渡动画。 这是个标准的数据状态切换问题。结果 AI 开始疯狂写各种通知监听器、计时器、复杂的 Guard 逻辑。结果: Previews 里的动画死活出不来。AI 的反应是:再加一层代码!

我不得不打断它: “大哥,视图是跟着数据走的。动画不出来是因为数据没变,别再堆垃圾代码了,直接用我们现有的 UserSettings 把昨天和今天的数据存进去不就结了吗?”

最终突破

一旦我把 AI 从“过度设计”的泥潭里拽出来,代码瞬间清爽:

  1. 数据存在 UserSettings 里。
  2. View 监听 .onChange(of: currentSnapshot)。
  3. 删掉了所有乱七八糟的单例状态机。
  4. Preview 神作:我在预览界面加了几个调试按钮,点一下“排名上升”,砰地一声,动画和撒花立马出来。

总结与感悟

这次折腾让我玩得挺开心。

几点干货:

  1. 别太迷信 AI:Claude Code 容易跑偏,一旦发现它在疯狂叠 Buff(写复杂逻辑),赶紧拉回来看 Spec。
  2. 宪法是照妖镜:有了宪法,AI 写出的代码风格跟我项目的统一感极强。
  3. 文档要实时更新:AI 是看文档长大的,别给它喂过期的“精神食粮”。

我不打算给整个 App 补 Spec,但以后任何新功能或者重大的 Bug 修复,我一定会用 Spec-Kit。这种“先想清楚、写清楚,再写代码”的感觉,确实让重构老项目少了很多焦虑。

最后的一句吐槽: 哪怕有了最顶级的 Spec,AI 还是会在一些基础的逻辑上翻车。不过没关系,比起它帮我省下的时间,这点学费我交得起!

最新文章

随机文章