问题背景
fork 了一个第三方 macOS 应用,原 release 版本未签名,但提供了源码,为Swift Package格式,需要重新签名并公证后分发。
遇到的坑
1. Swift Package Manager 无法启用 Hardened Runtime
问题:使用 swift build 构建的可执行文件,无法通过签名添加 hardened runtime。公证时一直报错:
The executable does not have the hardened runtime enabled.
原因:Swift Package Manager 构建时不会启用 hardened runtime,签名时添加也不被认可。
解决:使用 XcodeGen 生成 Xcode 项目,在项目配置中启用。
2. Apple Development 证书无法公证
问题:最初只有 Apple Development 证书(用于开发调试),公证时报错:
The binary is not signed with a valid Developer ID certificate.
原因:公证必须使用 Developer ID Application 证书,不能用 Apple Development。
解决:在 Apple Developer 账号中添加 Developer ID Application 证书。
3. 时间戳问题
问题:签名缺少安全时间戳:
The signature does not include a secure timestamp.
解决:在签名配置中添加 --timestamp 参数。
4. get-task-allow entitlement 问题
问题:分发版本包含开发用 entitlement:
The executable requests the com.apple.security.get-task-allow entitlement.
解决:在 entitlements 配置中明确设置 com.apple.security.get-task-allow: false。
经验教训
证书类型
| 证书类型 | 用途 |
|---|---|
| Apple Development | 开发调试,不能公证 |
| Developer ID Application | 分发和公证 ✅ |
签名配置要点
- Hardened Runtime - 必须启用
- 时间戳 - 必须添加
- entitlements - 分发版本禁止包含 get-task-allow
- 使用 Manual 签名 - 避免自动签名冲突
最佳实践(简单有效)
1. 使用 Xcode 项目而非 SPM
# 安装 XcodeGen
brew install xcodegen
# 配置 project.yml(关键设置)
targets:
YourApp:
settings:
base:
ENABLE_HARDENED_RUNTIME: YES
CODE_SIGN_STYLE: Manual
CODE_SIGN_IDENTITY: "Developer ID Application: Your Name (TEAM_ID)"
OTHER_CODE_SIGN_FLAGS: "--timestamp"
entitlements:
properties:
com.apple.security.get-task-allow: false
# 生成项目
xcodegen generate
# 构建
xcodebuild -project YourApp.xcodeproj -scheme YourApp -configuration Release build
2. 验证签名
codesign -dvv YourApp.app/Contents/MacOS/YourApp
确认输出包含:
flags=0x10000(runtime)- hardened runtime 已启用Timestamp=...- 有时间戳
3. 公证流程
# 1. 创建 zip
zip -r YourApp.zip YourApp.app
# 2. 提交公证(需要 App 专用密码)
xcrun notarytool submit YourApp.zip \
--apple-id "your@email.com" \
--password "app-specific-password" \
--team-id "TEAM_ID"
# 3. 等待完成
xcrun notarytool wait <submission-id> --apple-id "your@email.com" --password "password" --team-id "TEAM_ID"
# 4. 附加票据
xcrun stapler staple YourApp.app
总结
最简单有效的方式:
- 用 XcodeGen 生成 Xcode 项目(不要用纯 SPM)
- 在
project.yml中配置好签名和 hardened runtime - 用 xcodebuild 构建
- 用 notarytool 公证
不要试图用 swift build + 手动签名的方式来处理需要公证的分发版本,SPM 的构建产物不兼容。