这是一份针对 iOS 签名错误的诊断指南,专注于首次提交和 TestFlight 上传时遭遇的拦路错误——解释每条晦涩提示的真实含义及解决方法。本文不是完整的 App Store 提交流程说明——如需了解完整流程,请参阅首次 App Store 提交。
iOS 签名存在三个 Mac 签名没有的协调难题:
developer.apple.com 上,Xcode 在本地缓存一份副本。两者不一致时,构建会失败,而报错信息两个地方都不提。developer.apple.com 的 App ID 上启用,并且在项目的权限文件(entitlements file)中声明。只开其中一处,就会产生两处都不提的报错。模拟器完全免于上述所有限制——模拟器构建不需要签名或配置 Profile。如果你的项目在模拟器上构建成功,但在真机或上传时失败,那问题一定出在签名层,而不是代码本身。
追查任何签名错误之前,先证明构建本身是正常的。先在模拟器上跑一遍:
xcodebuild build \
-project MyApp.xcodeproj \
-scheme MyApp \
-destination 'generic/platform=iOS Simulator'
如果这一步失败,问题在代码,不在签名——先把代码修好。如果成功,那么之后在真机上或 Archive 时出现的每一次失败,都是签名问题,下面的诊断表格适用。
这是首次克隆项目后最经典的报错:
error: No account for team "ABCDE12345". Add a new account in
Accounts settings or verify your selected team is correct.
这条报错并不是说该团队不存在,而是说你的 Xcode(以及 LingCode 调用 xcodebuild 时)没有登录任何隶属于该团队的 Apple ID。通常有三种情况会导致这个问题:
DEVELOPMENT_TEAM 固定到了某个团队 ID,而你当前的 Apple ID 属于另一个团队。要么修改项目的 DEVELOPMENT_TEAM,要么添加正确的 Apple ID。不打开 Xcode 也能查到项目的 Team ID:
grep -A1 DEVELOPMENT_TEAM MyApp.xcodeproj/project.pbxproj | head -10
然后去 developer.apple.com/account 确认该团队确实在你的账号下。
两种签名模式,各有各的失败特征:
developer.apple.com 所需的凭据很难以脚本方式提供。务实的分工方式:本地开发用自动签名,Archive/发布用手动签名。可以在 Xcode > Signing & Capabilities 中按 Debug/Release 配置分别设置"Automatically manage signing"。命令行方式如下:
# 自动签名(开发)
xcodebuild build \
-scheme MyApp \
-destination 'generic/platform=iOS' \
-allowProvisioningUpdates \
CODE_SIGN_STYLE=Automatic \
DEVELOPMENT_TEAM=ABCDE12345
# 手动签名(发布 / CI)
xcodebuild archive \
-scheme MyApp \
-archivePath build/MyApp.xcarchive \
-destination 'generic/platform=iOS' \
CODE_SIGN_STYLE=Manual \
DEVELOPMENT_TEAM=ABCDE12345 \
PROVISIONING_PROFILE_SPECIFIER="MyApp Distribution" \
CODE_SIGN_IDENTITY="Apple Distribution: Your Name (ABCDE12345)"
-allowProvisioningUpdates 这个标志让 xcodebuild 能与 Apple 服务器通信以刷新 Profile。不加这个标志,CI 环境中的自动签名构建会报"no provisioning profile matches"。
一项能力需要在两处同时开启,两处必须保持一致:
developer.apple.com/account/resources/identifiers——能力复选框(推送通知、iCloud、Sign in with Apple、应用内购买、App Groups、Associated Domains 等)。MyApp.entitlements)——XML 键值对,与这些能力一一对应。不一致时会出现的报错:
Provisioning profile "iOS Team Provisioning Profile: com.you.MyApp"
doesn't include the aps-environment entitlement.
这意味着你的权限文件声明了推送通知(aps-environment),但 developer.apple.com 上的 App ID 并未开启推送通知。解决方法:在门户上开启后重新生成 Profile,或者从项目里移除该权限声明。
The executable was signed with invalid entitlements. The
entitlements specified in your application's Code Signing
Entitlements file do not match those specified in your
provisioning profile.
根本原因相同,只是报错信息不同——权限文件与 Profile 不一致。修复顺序永远是:先在门户上改,再重新生成 Profile,再让 Xcode 拉取最新版本。
可以让 LingCode 帮你把已构建应用的当前权限导出来做一次核对:
codesign -d --entitlements - build/MyApp.app
以及查看 Provisioning Profile 实际授予了哪些权限:
security cms -D -i build/MyApp.app/embedded.mobileprovision
如果这两份输出的权限列表不一致,那就是问题所在。
这条报错有六种常见原因,按顺序逐一排查:
PRODUCT_BUNDLE_IDENTIFIER)与门户上的 App ID 不一致,重命名后最常见。用 grep PRODUCT_BUNDLE_IDENTIFIER MyApp.xcodeproj/project.pbxproj 核对。同一条报错信息可能对应以上六种情况中的任意一种,逐项排查,不要猜。
每次变更能力、轮换证书或添加设备后,Xcode 里缓存的 Profile 就已经过时了。修复方式每次都一样:
developer.apple.com/account/resources/profiles。.mobileprovision 文件,双击安装到 Xcode 中。xcodebuild -allowProvisioningUpdates …,让 Xcode 自行拉取刷新后的 Profile。漏掉门户上"Edit > Save"这一步,是重新下载后仍然报同样错误的最常见原因——门户在保存时触发重新生成,而不是在下载时。
如果 iOS Archive 出现 errSecInternalComponent,原因与 macOS 上相同:运行 xcodebuild(或 LingCode,或 CI worker)的进程没有获得完全磁盘访问权限,无法从 Keychain 读取签名密钥。这条报错与 Keychain 损坏的报错完全相同,所以很多人会追错方向。
解决方法:
如果已经授权了完全磁盘访问但错误依旧,那才是 Keychain 本身的问题——打开 Keychain Access,找到签名证书,双击私钥,检查访问控制是否允许 codesign。
自动签名很好用,直到它不管用为止。以下情况建议切换到手动签名:
手动签名用可见性换便利性——每一个错误都对应一个明确的门户操作,而不是 Xcode 黑盒式的自动协调。
将这个 skill 放入 LingCode 的 skills 文件夹,让 LingCode 帮你诊断任何 iOS 签名错误——它会替你走完整个诊断流程:
---
name: ios-signing-and-app-store
description: Use when shipping an iOS app to TestFlight or the App Store — Apple Developer enrollment, automatic signing, capabilities provisioning, archive, export, and notarytool/Transporter upload. Triggers: 'No account for team', 'No matching provisioning profile', 'TestFlight upload fails', 'App Store submission', 'iOS signing error', capability/entitlement sync failure, simulator-doesn't-need-signing baseline question, errSecInternalComponent during xcodebuild. Actions: prove simulator builds, pick automatic vs manual signing, fix entitlement drift, run notarytool, upload via Transporter. Errors: 'No account for team X', 'Capabilities X requires entitlement', expired profile, bundle ID mismatch. Skip if: just running on simulator.
---
Diagnose and fix iOS signing errors.
Step 0 — Prove the simulator builds clean. Simulator doesn't
sign; if simulator fails, the problem is code, not signing.
Step 1 — Resolve "No account for team": confirm the project's
DEVELOPMENT_TEAM matches an Apple ID added in Xcode > Settings >
Accounts. Re-auth on 2FA lapse.
Step 2 — Pick signing mode deliberately. Automatic for local dev
with -allowProvisioningUpdates. Manual for release/CI with
PROVISIONING_PROFILE_SPECIFIER and CODE_SIGN_IDENTITY pinned.
Step 3 — Capability/entitlement sync: a capability must be
enabled BOTH on the App ID at developer.apple.com AND in the
entitlements file. Verify with codesign -d --entitlements - and
security cms -D -i embedded.mobileprovision.
Step 4 — "No matching provisioning profile" walks six causes:
bundle ID mismatch, wrong profile type, expired profile,
unsynced capability, missing device, dead certificate.
Step 5 — After ANY portal change: Edit > Save the profile on
developer.apple.com (regenerates), then re-download or use
-allowProvisioningUpdates.
Step 6 — errSecInternalComponent = host process missing Full
Disk Access (same as macOS). Fix in System Settings, restart
terminal session.
Step 7 — Escalate to manual signing if automatic has failed
twice in a row.
保存为 ~/.lingcode/skills/ios-signing-and-app-store/SKILL.md——具体位置及 skill 的发现机制请参阅安装 Skill。