【AICoding】用 AI 全自主开发一款 macOS 截图工具的全流程实践
一个人 + AI,3 天时间,3500 行 Swift 代码,8 个版本迭代,一款功能完备的 macOS 截图工具。
背景:为什么做这件事
macOS 自带的截图功能(Cmd+Shift+4)虽然够用,但和 Windows 上的 Snipaste、macOS 上的 iShot 相比,缺少标注、贴图、OCR 等高频需求。作为一个开发者,截图标注几乎是每天都要重复几十次的操作。
问题是:开发一款 macOS 桌面应用,门槛有多高?
传统的回答是:你需要熟悉 Swift/SwiftUI、AppKit 框架、Core Graphics 绘图、Vision OCR、窗口管理、权限体系、签名分发……每一项都需要相当的学习成本。
但如果全程由 AI 来写代码呢?我决定做一个实验:让 AI 完全自主地完成一款 macOS 截图工具的开发,从架构设计到功能实现,从 Bug 修复到构建打包,看看 AI 编程到底走到了哪一步。
这就是 AliooScreenshot 的由来。
最终成果
先说结论。经过约 3 天的迭代开发,最终交付的应用具备以下能力:
| 功能模块 | 具体能力 |
|---|---|
| 核心截图 | 全局快捷键触发、全屏/区域截图、多显示器自动检测、自动复制到剪贴板 |
| 标注工具 | 矩形框、箭头、文字、马赛克、序号标注,全部支持拖拽移动 |
| 编辑能力 | 撤销/重做、选区调整、8 方向拖拽修改区域 |
| 滚动截图 | 自动滚动拼接长页面、实时预览、到底自动检测 |
| OCR 文字识别 | 基于 Apple Vision 框架,中英文识别,独立窗口预览,一键复制 |
| 贴图功能 | 截图钉在屏幕上,支持拖拽移动,多贴图并存 |
技术栈:Swift 5.9 + AppKit + Core Graphics + Vision,使用 Swift Package Manager 构建,目标平台 macOS 13.0+。
代码规模:12 个 Swift 源文件,3,586 行代码,20 次 Git 提交,8 个版本迭代(v1.0 → v1.8.0)。
开发全流程拆解
第一阶段:MVP — 从 0 到 v1.0
时间: 第 1 天下午
提交记录: feat: 完整的截图工具 v1.0
第一步不是写代码,而是让 AI 理解我们要做什么。我提供了参考产品(iShot Pro)的功能列表,并要求 AI 先输出架构设计文档。
AI 产出了一份 五层分层架构:
应用层 (main.swift)
↓
业务逻辑层 (ScreenshotManager)
↓
UI 层 (ScreenshotWindow / ScreenshotView / Toolbar)
↓
服务层 (OCRService / ScrollCaptureController / PinManager)
↓
数据模型层 (Annotation)
这个架构贯穿了后续所有的开发,每个新功能都被准确地添加到对应的层级中。
v1.0 实现了最核心的截图流程:
- 按下
Ctrl+Cmd+A触发截图 - 全屏覆盖透明窗口,用户拖拽选择区域
- 支持矩形框、箭头、文字三种基础标注
- 确认后自动复制到剪贴板
这个版本的代码约 1,500 行,已经是一个可用的截图工具了。
关键的技术决策(AI 自主做出的):
- 使用 Carbon API 的
RegisterEventHotKey注册全局快捷键,而非更现代的 NSEvent monitor — 因为后者在某些场景下不可靠 - 使用
CGWindowListCreateImage捕获屏幕而非CGDisplayCreateImage— 前者通过窗口服务器合成,性能更好 - 使用 NSPanel 而非 NSWindow 作为覆盖窗口 — 避免与 ReplayKit 冲突,且透明窗口支持更好
这些决策显示了 AI 对 macOS 底层框架有相当深入的理解。
第二阶段:标注工具补全 — v1.1 到 v1.2
时间: 第 1 天晚上
关键提交:
feat: 添加马赛克和序号标注工具feat: 实现撤销/重做功能feat: 添加数字快捷键切换标注工具
马赛克标注的实现值得一提。AI 选择了棋盘格像素化的方案 — 不是简单的高斯模糊,而是将选区分割为固定大小的色块,取每个色块的平均颜色填充。这种方式在视觉上更接近「马赛克」的直觉,且计算成本极低。
序号标注(①②③)则展示了 AI 对细节的关注:它自动维护一个递增计数器,每次放置序号标注时自动加一,且在撤销/重做时正确回退/前进。
撤销/重做的实现采用了经典的命令栈模式:
用户操作 → 压入 undoStack → 清空 redoStack
Cmd+Z → undoStack.pop() → 恢复到上一步 → 压入 redoStack
Cmd+Shift+Z → redoStack.pop() → 重新执行 → 压入 undoStack
第三阶段:贴图与交互打磨 — v1.3 到 v1.5
时间: 第 2 天上午
关键提交:
feat: 实现贴图功能 (Pin)fix: 实现自定义浮动提示,解决工具栏按钮 tooltip 不显示问题feat: 选区调整 - 拖拽角落修改区域feat: 支持拖拽移动已有标注
贴图功能的实现相对顺利:创建一个浮动 NSPanel 窗口,层级设为 .screenSaver(确保在最前),显示截图内容,支持鼠标拖拽移动。
但在交互打磨阶段,AI 遇到了一个典型的 macOS 开发陷阱:NSButton 的 tooltip 在 borderless NSPanel 中不显示。这是 AppKit 的一个已知行为 — tooltip 依赖窗口成为 key window,而 borderless panel 默认不会成为 key window。
AI 的解决方案很务实:自己实现一个浮动提示系统。当鼠标悬停在工具栏按钮上时,创建一个自定义的 tooltip 窗口,跟随鼠标位置显示。这比试图修复 AppKit 的默认行为更可靠。
选区调整和标注拖拽的实现则涉及大量的坐标计算和命中检测。特别是标注的命中检测,需要为每种标注类型实现不同的算法:
- 矩形框:判断点是否在矩形边框的容差范围内
- 箭头:计算点到线段的距离
- 文字:基于文字 bounding box 的矩形检测
- 马赛克:和矩形框类似的区域检测
第四阶段:滚动截图 — v1.6 到 v1.7
时间: 第 2 天下午到晚上
关键提交:
feat: 实现滚动截图 + 扩展快捷键至 1-7feat: 修复滚动截图并增加实时预览
滚动截图是整个项目中技术难度最高的功能。它的核心流程是:
- 用户选定区域后,隐藏覆盖窗口
- 找到选区下方的应用窗口并激活它
- 发送模拟滚动事件,同时截取每一帧
- 检测相邻帧之间的重叠区域
- 去除重叠后垂直拼接所有帧
- 检测是否已滚动到底部(连续两帧相似)
图像拼接算法是最核心的部分。AI 实现的 findVerticalOverlap 函数从最大可能重叠量开始向下搜索,逐行比较两帧图像的像素相似度。为了性能,使用了步长采样(不是逐像素比较,而是每隔 N 个像素取一个样本),以及提前终止(找到足够好的匹配就停止)。
到底检测则使用了一个巧妙的启发式:如果连续两帧图像高度相似(说明页面已经不再滚动),则认为已经到底。
实时预览是后来追加的功能 — 在拼接过程中动态更新预览窗口,让用户看到长图正在逐步生成,而不是等到全部完成后才显示结果。
第五阶段:OCR 文字识别 — v1.8
时间: 第 3 天上午
关键提交: feat: 新增 OCR 文字识别功能
OCR 功能利用了 Apple 的 Vision 框架,完全在本地运行,不联网。实现流程:
选区图像裁剪 → VNRecognizeTextRequest → 文字识别结果
→ 按 boundingBox 位置排序 → 拼接为完整文本
→ 弹出独立预览窗口 → 一键复制
Vision 框架的配置选择了高精度模式(.accurate),开启了语言纠错(usesLanguageCorrection),同时支持中英文(["zh-Hans", "en"])。实测一张截图的识别时间通常在 100-500ms 内完成。
OCR 结果的展示也经过设计:弹出一个独立的浮动面板,显示识别出的文字内容和字符计数,底部一个「复制全部」按钮。复制后有短暂的「已复制 ✓」反馈。
构建与打包
AI 不仅写了应用代码,还自主完成了整个工程化体系:
Swift Package Manager
let package = Package(
name: "alioo-screenshot",
platforms: [.macOS(.v13)],
products: [.executable(name: "AliooScreenshot", targets: ["alioo-screenshot"])],
targets: [.executableTarget(name: "alioo-screenshot")]
)
没有使用 Xcode 项目文件(.xcodeproj),而是纯 SPM 构建。这意味着整个项目可以在终端中用 swift build 一条命令编译,非常适合 AI 驱动的开发模式。
构建脚本
build.sh 完成了从编译到安装的全流程:
- 关闭正在运行的应用
- 清理旧 TCC 权限记录(
tccutil reset) - 编译 Release 版本
- 打包为 .app bundle
- Ad-hoc 代码签名
- 复制到
/Applications
其中 TCC 权限清理这一步特别值得注意。因为 ad-hoc 签名每次构建都会产生不同的 CDHash,macOS 的权限系统通过 CDHash 追踪授权,导致旧权限失效。AI 在构建脚本中自动执行 tccutil reset 来解决这个问题,并在注释中详细解释了原因和替代方案(使用 Apple Developer ID 证书)。
架构文档
AI 主动维护了一份 ARCHITECTURE.md(630+ 行),包含分层架构图、组件关系、数据流、状态机、坐标系转换公式、约束条件等。这份文档在后续迭代中被持续更新,确保 AI 在每次开发时都能快速恢复上下文。
开发过程中的关键观察
1. AI 的架构能力超出预期
AI 在项目初始阶段就设计了清晰的分层架构,并且在 8 个版本的迭代中始终遵守这个架构。新功能被准确放入对应的层级,没有出现「面条代码」的退化。
2. 对 macOS 底层框架的理解深入
几个例子:
- 选择 Carbon API 的
RegisterEventHotKey而非NSEvent.addGlobalMonitorForEvents来实现全局快捷键,因为后者在辅助功能权限未授予时静默失败 - 使用 NSPanel 替代 NSWindow 避免与屏幕录制框架冲突
- 正确处理了 NSView 和 CGImage 之间的坐标系转换(左下角原点 vs 左上角原点)
3. 迭代式开发模式非常有效
每个版本只做一件事,先跑通再优化:
- v1.0:基础截图 → 能用
- v1.1:补全标注工具 → 好用
- v1.3:贴图 → 更方便
- v1.6:滚动截图 → 长页面也能截
- v1.8:OCR → 文字也能提取
这种小步快跑的方式让 AI 始终在一个可控的代码库上工作,每次改动的影响范围有限。
4. AI 能主动修复自己的 Bug
在 20 次提交中,有 6 次是 fix 类型的提交。例如:
- 贴图拖拽性能问题 → 优化事件处理逻辑
- 角落提示方向错误 → 修正形状方向
- tooltip 不显示 → 自行实现浮动提示
AI 在引入 Bug 后能够在后续迭代中识别并修复,这说明它具备了一定的自我纠错能力。
5. 人类的角色:产品经理 + 测试员
在整个开发过程中,人类的角色主要是:
- 提需求:「加一个马赛克标注」「支持滚动截图」「加个 OCR」
- 测功能:运行应用,实际操作,发现 Bug
- 定优先级:决定先做哪个功能
不需要写一行 Swift 代码,不需要理解 AppKit 的 API,甚至不需要知道坐标系怎么转换。
当前局限与后续规划
已知的局限
- 仅支持 Apple Silicon — 当前只编译了 arm64 架构,Intel Mac 用户无法使用
- Ad-hoc 签名 — 未公证,分发给其他用户时会触发 Gatekeeper 安全警告
- 无保存功能 — 截图只能复制到剪贴板,不能保存为文件
- 无窗口截图 — 不支持自动识别和截取整个窗口
规划中的功能
| 优先级 | 功能 | 说明 |
|---|---|---|
| 高 | 窗口截图 | 鼠标悬停高亮窗口,点击截取 |
| 高 | 延时截图 | 3/5/10 秒倒计时后截取 |
| 高 | 保存到文件 | 支持 PNG/JPG,弹窗选择路径 |
| 中 | 标注编辑 | 调整大小、改颜色 |
| 中 | 取色器 | 获取屏幕像素颜色值 |
写在最后
这次实践证明了一件事:AI 全自主开发一款功能完备的 macOS 桌面应用,在今天已经是可行的。
3,586 行 Swift 代码,涵盖了全局快捷键、屏幕捕获、图像标注、滚动拼接、OCR 文字识别、多窗口管理、权限处理、构建打包等方方面面。代码质量良好,架构清晰,功能完整可用。
当然,这不意味着 AI 可以替代所有的软件开发工作。这个项目的特点是:需求明确、功能独立、不涉及复杂的系统集成。在这些条件下,AI 的表现令人惊喜。
AI 编程的真正价值可能不在于取代程序员,而在于:让有想法但没有编程技能的人,也能把自己的工具做出来。
一个对 macOS 截图工具有想法的人,现在可以通过和 AI 对话,在 3 天内得到一款可用的产品。这在几年前是不可想象的。
截图效果预览

AliooScreenshot 项目使用 Swift 5.9 + AppKit 开发,支持 macOS 13.0+,源码可联系作者 获取。
1794

被折叠的 条评论
为什么被折叠?



