概览
使用 Codex 构建 macOS SwiftUI 应用,串联以 shell 为先的构建与运行循环,并随着应用逐步成熟,添加桌面原生的 scene、window、AppKit 以及签名工作流。
适合场景
- 适用于从零开始的 macOS SwiftUI 应用:你希望 Codex 搭建一个桌面原生的应用骨架和可重复使用的构建脚本
- 适用于现有 Mac 应用:Codex 需要处理窗口、菜单、侧边栏、设置、AppKit 互操作或签名问题
- 适用于希望 macOS 开发保持以 shell 为先,同时仍遵循原生桌面 UX 约定的团队
搭建原生 Mac 应用
使用 Build macOS Apps plugin 搭建一个基础的 macOS SwiftUI 应用,并添加一个项目本地的 `script/build_and_run.sh` 入口,我可以将其连接到 `Run` 动作。 约束: - 保持以 shell 为先。对于 Xcode 项目优先使用 `xcodebuild`,对于以 package 为先的应用优先使用 `swift build`。 - 明确建模 Mac scenes:包含一个主窗口,并且只在符合产品需求时才加入 `Settings`、`MenuBarExtra` 或工具窗口。 - 优先使用桌面原生的侧边栏、工具栏、菜单、键盘快捷键和系统材质,而不是 iOS 风格的推入式导航。 - 只有在 SwiftUI 无法干净地表达桌面行为时,才使用精简的 AppKit 桥接。 - 每次更改都保持一个小型验证循环,并准确告诉我你运行了哪些构建、启动或日志命令。 交付内容: - 应用骨架或所请求的 Mac 功能切片 - 可复用的构建与运行脚本 - 你运行过的最小验证步骤 - 你建议的任何桌面特定后续工作
搭建应用和构建循环
对于新的 Mac 应用,先让 Codex 选择合适的 scene 模型:WindowGroup、Window、Settings、MenuBarExtra 或 DocumentGroup。这样从第一版开始,应用就能保持桌面原生,而不是从 iOS 风格的 ContentView 逐渐演变过来。
保持执行循环以 shell 为先。对于 Xcode 项目,使用 xcodebuild。对于以 package 为先的应用,使用 swift build,并配合项目本地的 script/build_and_run.sh 包装脚本:停止旧进程、构建应用、启动新产物,并可选择暴露日志或遥测信息。
如果纯 SwiftPM 应用是一个 GUI 应用,请将其打包并以 .app 形式启动,而不是直接运行原始可执行文件。这样可以避免在本地验证期间出现 Dock、激活和 bundle 标识缺失等问题。
利用 skills
当工作变得更偏向桌面特性时,添加 Build macOS Apps 插件。它涵盖以 shell 为先的构建和调试循环、SwiftPM 应用打包、原生 SwiftUI scene 和 window 模式、AppKit 互操作、统一日志、测试分诊,以及签名/公证工作流。
要了解如何安装和使用 plugins 与 skills,请参阅 Codex 插件文档 和 skills 文档。
构建桌面原生 UI
优先采用 Mac 约定,而不是 iOS 导航模式。对侧边栏/详情布局使用 NavigationSplitView,为偏好设置使用显式的 Settings scenes,使用工具栏和 commands 提供可发现的操作,并使用菜单栏扩展来承载轻量、始终可用的工具。
优先使用系统材质、语义颜色和标准控件。只有当产品确实需要独特的桌面表面时,再添加自定义窗口样式、拖拽区域或 Liquid Glass 表面。
如果 SwiftUI 已经很接近但还差一点,就添加尽可能小的 AppKit 桥接。典型例子包括打开/保存面板、first-responder 控制、菜单校验、拖放边缘处理,以及为某个专用控件包装一个 NSView。
调试、测试并为发布做准备
对于运行时行为,可以让 Codex 在窗口打开、侧边栏选择、菜单命令或后台同步等位置添加少量 Logger 事件,然后在应用启动后使用 log stream 验证这些事件。
对于失败的测试,让 Codex 先运行最小且有用的 xcodebuild test 或 swift test 范围,然后判断问题属于编译错误、断言失败、崩溃、偶发失败,还是环境/配置问题。
当工作从本地迭代转向分发时,可以让 Codex 同时准备 Xcode 中的手动归档路径,以及基于脚本的归档和公证路径,以支持可重复发布。让它用 codesign 和 plutil 检查 app bundle、entitlements 和 hardened runtime;如果你也希望上传流程保留在终端中,可以使用 App Store Connect CLI。
示例提示词
实用技巧
保持 scene 显式
将主窗口、设置窗口、工具窗口和菜单栏扩展建模为彼此独立的 scene 根,而不是把整个应用都藏在一个巨大的视图里。
让系统 chrome 承担更多工作
在创建自定义侧边栏、工具栏或材质之前,先检查标准 SwiftUI scene 和 window API 是否已经能提供你想要的 Mac 行为。
将 AppKit 视为狭窄边界
使用 NSViewRepresentable、NSViewControllerRepresentable 或聚焦单一能力的 NSWindow 辅助工具来补足缺失的桌面能力,但让 SwiftUI 继续作为选择状态和应用状态的事实来源。
将签名和公证验证与本地构建成功分开对待
本地成功启动并不能证明应用已经完成签名或准备好进行公证。保留一条用于一次性发布检查的手动 Xcode 归档流程,再添加一条用于可重复分发的脚本化归档和公证流程;当任务关注的是发布而不仅仅是本地迭代时,运行 codesign 和 plutil 检查。
