Scott Willsey 12天前 · 2026-07-14 07:59:40 · 3 阅读
不打开 Xcode 也能构建和发布 Mac 与 iOS 应用
Building and Shipping Mac and iOS Apps Without Ever Opening Xcode
我多年来尝试过 Electron、Tauri、.NET MAUI 以及各种其他工具来做跨平台桌面和移动 App,结果总感觉差点意思——要么包体积臃肿,要么性能不行,要么功能受限于平台抽象层能做什么不能做什么。
Xcode 的问题
Xcode 是个巨兽。30+ GB 的 IDE,又慢又有 bug 还吃资源。对于业余爱好者或独立开发者来说,为了做点小事就打开它感觉杀鸡用牛刀。而且它是 Mac-only,想不靠 Mac 编译 iOS 应用的话基本没戏。
解决方案
Swift Package Manager(SPM)是 Apple 官方发布的 Swift 代码分发方案。它能构建可执行文件、库和 framework,但本身不能把它们打包成正经的 .app bundle。还需要别的东西把 SPM 编译出来的二进制包装成漂亮的应用。
工具栈
下面是作者最终采用的、完全命令行构建和发布 Mac/iOS 应用的工具组合:
- Swift Package Manager (SPM) — 构建系统和依赖管理器
- XcodeGen — 读取
project.yml文件并从中生成 Xcode 项目 - xcodebuild — 通过生成的项目编译所有内容
- actuator — 把 SPM 编译的二进制打包成正经的 .app bundle
为什么用 XcodeGen?因为 .xcodeproj 文件本质上是二进制 plist,在 Git 里 diff 和 merge 都是噩梦。XcodeGen 让你在 YAML 文件里定义项目结构,纯文本,对合并友好。
构建流程
project.yml (text)
↓
XcodeGen
↓
.xcodeproj (binary plist)
↓
xcodebuild
↓
SPM 构建可执行文件
↓
actuator
↓
.app bundle
↓
codesign + notarytool
↓
可分发的 .app
完整的构建脚本
#!/bin/bash
set -euo pipefail
# 从 project.yml 生成 Xcode 项目
xcodegen generate
# 用 xcodebuild 编译
xcodebuild -project MyApp.xcodeproj \
-scheme MyApp \
-configuration Release \
-derivedDataPath build
# 用 actuator 打包成 .app bundle
actuator package build/Build/Products/Release/MyApp.app/Contents/MacOS/MyApp \
--info-plist Info.plist \
--output MyApp.app
# 用 Developer ID 签名
codesign --force --deep --options runtime \
--sign "Developer ID Application: Your Name (TEAMID)" \
MyApp.app
# 用 notarytool 公证
xcrun notarytool submit MyApp.zip \
--key ~/.keys/AuthKey_ABC123.p8 \
--issuer-id YOUR_ISSUER_ID \
--wait
# 装订公证票据
xcrun stapler staple MyApp.app
分发
在 Mac App Store 之外分发需要签名和公证。对于业余项目,最简单的路径是:
- 用 App Store Connect API key 签名并上传到 App Store Connect
- 用 Developer ID 签名进行 App Store 之外的渠道分发
- 用
xcrun altool或xcrun notarytool进行公证(Notarization)
整个流程完全在命令行里跑通,再也不用打开 Xcode 这个 30+ GB 的 IDE 了。
原始来源: Scott Willsey