现象:真机运行时报
A device with number 'xxx' already exists on this team,紧接着一串provisioning profile doesn't include signing certificate / doesn't include the currently selected device / doesn't include the aps-environment entitlement。 折腾了半天,最后发现:设备被手动加到了另一个 Team 里。本文记录了完整排查路径、Apple 的设备年度规则,以及"证书和设备不在同一个 Team"这类问题的判断与修复方法。 文中截图已做打码处理(团队名、证书名、设备号、日期均已模糊)。
一、现象
在 Xcode 的 Signing & Capabilities 面板点真机运行,红字报错(节选):
There is a problem with the request entity.
A device with number '00008030-XXXXXXXXXXXX' already exists on this team.
Provisioning profile "iOS Team Provisioning Profile: com.example.app" doesn't include signing certificate "Apple Development: <name> (<ID>)".
Provisioning profile "iOS Team Provisioning Profile: com.example.app" doesn't include the currently selected device "iPhone (00008030-XXXXXXXXXXXX)".
Provisioning profile "iOS Team Provisioning Profile: com.example.app" doesn't include the aps-environment entitlement.
No profiles for 'com.example.app' were found.
同时在 Xcode 设置里能看到团队、证书都在,看起来"什么都没问题"。这就是它难排查的地方——每一条报错都只是症状,真正的原因只有一个。
二、背景:iOS 真机签名到底要几样东西
真机跑 App,Apple 要求下面四件套全部对齐,任何一个换了(换电脑、换账号、删证书、换手机)都要重新走一遍。
| 组成 | 作用 | 归属 |
|---|---|---|
| 证书(Apple Development) | 证明"你是谁" | 属于某个 Team,且私钥必须在本机钥匙串 |
| App ID | 标识这个 App | 属于某个 Team,Bundle ID 要匹配 |
| 设备 | 允许安装到哪台手机 | 注册在某个 Team 下,用 UDID 标识 |
| 描述文件(Provisioning Profile) | 把上面三者绑定在一起 | 由 Team 签发,里面有:App ID + 证书 + 设备列表 + 权限 |
Xcode 的"自动管理签名"(Automatically manage signing)背后做的其实就是三步:
- 找/建一张属于当前选定 Team 的证书
- 把连接的手机注册到当前选定 Team 的设备列表
- 生成一个包含「证书 + 设备 + App ID + 权限」的描述文件,安装到手机上
关键在于第 2 步:设备必须注册在你签名用的那个 Team 里。注册到别的 Team,这里就永远走不通。
三、报错逐条翻译
| 报错 | 真实含义 |
|---|---|
device already exists on this team | Xcode 想"新增设备",但 Apple 说这台设备已有记录 → 冲突,流程中断 |
doesn't include signing certificate | 描述文件里没有你本机这把证书(证书重建过、或 profile 是旧的) |
doesn't include the currently selected device | 描述文件不包含这台手机 |
doesn't include the aps-environment entitlement | 描述文件是通配符(*)的,没有推送权限 → 说明它退而求其次抓了个"凑数"的 profile |
No profiles for 'xxx' were found | 本地一个可用描述文件都没有(清过缓存后常见) |
⚠️ 第一条出现后,后面几条都是它的连带伤害:Xcode 在"注册设备"失败后会中断,然后抓一个通配符 profile 凑数,于是又冒出证书/设备/推送三连报错。所以先解决第一条。
四、排查用到的命令(可直接复制)
1. 看本机有哪些"可用身份"(证书 + 私钥)
security find-identity -v -p codesigning
只有"证书 + 私钥"都在的身份才会出现在这里。 列表里没有你的证书,就说明本机签不了——要么证书不在,要么私钥在别的电脑上。
2. 看证书属于哪个 Team
security find-certificate -c "Apple Development: <名字>" -Z
# 或者看全部证书的 OU(Team ID)
security find-certificate -a -p | openssl x509 -noout -subject | grep -o 'OU=[A-Z0-9]*'
3. 看本机装了哪些描述文件、它们属于谁
ls -lt "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"
4. 解码描述文件,确认"四件套"是否对齐
security cms -D -i "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles/<UUID>.mobileprovision" > /tmp/p.plist
plutil -p /tmp/p.plist | grep -E "Name|TeamIdentifier|ProvisionedDevices|aps-environment|application-identifier|ExpirationDate"
输出里要重点看四行:
"application-identifier" => "<TeamID>.com.example.app" ← App ID 属于哪个 Team
"aps-environment" => "development" ← 权限有没有
"ProvisionedDevices" => [ ... 设备 UDID 列表 ... ] ← 有没有你的手机
"TeamIdentifier" => [ "<TeamID>" ] ← 哪个 Team 签的
5. 看工程实际用的是哪个 Team
grep -n "DEVELOPMENT_TEAM" YourApp.xcodeproj/project.pbxproj
⚠️ 这里经常有坑:Debug / Release 两个配置可能是不同的 Team(比如换团队时只在 Xcode 里改了一次),Project 级还可能残留第三个值。Debug 能跑不代表 Release 能打包。
6. 看连接的真机
xcrun devicectl list devices
# 或
xcrun xcdevice list | grep -E "name|identifier"
7. 看 Xcode 里登录了哪些 Team、各自有几台设备
Xcode → Settings → Accounts → 点开对应 Team,会显示 N Provisioned Devices。
五、真凶:设备注册在"哪个 Team"
这是本次排查最关键的发现。同一个 Apple ID 登录了两个 Team,各自设备数完全不同:
Team A(公司 Team):6 台设备
Team B(个人 Team):15 台设备
而手机只被手动注册进了 Team A,工程的 DEVELOPMENT_TEAM 却指向 Team B。于是:
Xcode 用 Team B 去签名
→ 检查 Team B 的设备列表
→ 没有这台手机(它加在 Team A 里)
→ 尝试注册到 Team B
→ Apple 返回"设备已存在,无法新增"(因为它已经存在于你的账号体系里)
→ Xcode 报 409 并中断
→ 生成不了 profile → 后面 4 条报错全部跟着出现
最反直觉的地方在于报错文案:already exists on this team 中的 "this team" 指的是 Xcode 正在签名的那个 Team,而你手动加设备时很可能加在了另一个 Team。文案不会告诉你"你加错团队了",只会说"已存在",非常容易误判成"Apple 后台有僵尸记录,删不掉"。
怎么快速确认
把这三个值摆在一起对比,不一致就是问题:
1. 工程里的 DEVELOPMENT_TEAM(命令 5)
2. 证书的 OU / TeamIdentifier(命令 2)
3. 手机注册在哪个 Team(Xcode Accounts 里看 "N Provisioned Devices",或 portal 里切 Team 看 Devices)
三个一致 → 自动签名基本能过;有一个不同 → 必然报错。
六、Apple 的设备年度规则:为什么有时候"删不掉"
排查过程中很容易卡在"想删掉那条冲突的设备记录,但只有 Disable 按钮"。这不是权限问题,是 Apple 的设备年度规则:
| 规则 | 说明 |
|---|---|
| 每类设备上限 100 台 | iPhone/iPad 等各算一类,每个会员年度统计一次 |
| 删除名额不返还 | 当年删掉设备,名额也不会释放,要等年度重置 |
| 只有"本会员年度内新增"的设备可以删除 | 往年注册的设备只能 Disable,不能 Delete |
| 会员到期/续费后年度重置 | 新年度开始,上一年的设备记录才会变成"可删除" |
续费前后的差别
续费到期前(当前年度内):
- 今年新注册的设备 → 可以 Delete,也可以 Disable
- 往年注册的设备 → 只能 Disable,Delete 按钮不出现
- 想"删掉重加"旧设备 → 做不到,只能等年度重置
续费之后(新年度开始):
- 上一年度的设备记录全部进入可删除状态
- 可以清掉历史记录,重新注册,避免"设备记录僵住"
- 100 台的名额也重新计算
所以遇到"设备删不掉"时
- 先确认是不是在正确的 Team 页面(多 Team 账号经常切错,公司 Team 里看到的旧设备本来就不能删)
- 确认这台设备是不是本年度新增的(portal 列表里有"注册日期"这一列)
- 都不是 → 只能 Disable,或者等年度重置后删除
- 最快的绕法:不要去删记录,而是让「签名 Team」和「设备所在 Team」对齐(见下一节)
七、证书与设备不一致的五种典型场景
| 场景 | 表现 | 原因 |
|---|---|---|
| 多 Team 混用 | 证书 Team ≠ 设备 Team | 手动加设备时选错了 Team,或工程 Team 被改过 |
| 证书重建后 profile 未重建 | doesn't include signing certificate | profile 里记录的是旧证书 ID |
| 证书被吊销 | 0 valid identities found,钥匙串里显示 CSSMERR_TP_CERT_REVOKED | 同 Team 证书超限(新建自动吊销旧的)、或被人手动 Revoke、或会员状态变更 |
| 新设备未进 profile | doesn't include the currently selected device | 设备是新的,profile 是旧的 |
| Debug/Release Team 不一致 | 模拟器/Debug 正常,Archive 报签名错误 | 只在 Xcode 里改过一次 Team,另一个配置没同步 |
还有一个隐蔽的:证书在、私钥不在。别的电脑生成的证书下载到本机后,security find-identity 里根本不会出现——因为私钥不在本机。这种只能让生成证书的那台机器导出 .p12,或者直接在本机重建证书。
八、解法(按推荐顺序)
方案一:让 Team 对齐(最优,能保住自动签名)
- 确定手机注册在哪个 Team(portal 里切 Team → Devices 查找 UDID)
- 把工程的
DEVELOPMENT_TEAM改成那个 Team(Debug/Release 都要改) - Xcode → Signing → 重新勾
Automatically manage signing→ Try Again
Team 对齐后,Xcode 发现"设备已在列表中",就不会再走"注册设备"这一步,409 自然消失,managed profile 自动生成。
方案二:手动 profile(最稳,绕开所有自动流程的坑)
- portal → Profiles → + → iOS App Development
- 选 App ID、勾当前 Team 的证书、勾目标设备(能勾就行,不用删除记录)
- Generate → Download → 双击安装
- Xcode → Signing → 取消
Automatically manage signing,改为 Manual,选刚安装的 profile
优点:完全绕开 Xcode 的"注册设备"动作,不受 409 影响。描述文件通常一年有效,到期前重新生成即可。
方案三:清理本地状态(前面都失败时再试)
# 退出 Xcode 后执行
defaults delete com.apple.dt.Xcode DVTDeveloperAccountManagerAppleIDLists
defaults delete com.apple.dt.Xcode IDEProvisioningTeamByIdentifier
rm -rf "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"/*
然后重新登录 Apple ID,让 Xcode 重新拉取团队~设备列表。
⚠️ 两个提醒:
- 重登基本一定会要双重认证验证码,本地清不掉
- 清缓存不会删掉 Apple 后台的设备记录,所以只有"本来就是缓存问题"时才有效
关于命令行
xcodebuild -workspace App.xcworkspace -scheme App \
-destination 'platform=iOS,id=<UDID>' \
-allowProvisioningUpdates build
注意 -allowProvisioningUpdates 和 -allowProvisioningDeviceRegistration 的区别:
- 前者:允许更新/生成 profile(不新增设备)
- 后者:允许把新设备注册到 Team
两个都加时,还是会去注册设备,仍可能撞 409。命令行报 No Accounts 通常不是没登录,而是跑命令的终端拿不到钥匙串里的账号会话(比如在受限环境里执行)。
九、一页速查清单
排查真机签名问题时,按这个顺序走,基本 5 分钟定位:
# ① 有没有可用证书(证书+私钥)
security find-identity -v -p codesigning
# ② 工程用的是哪个 Team(注意 Debug/Release 可能不同)
grep -n "DEVELOPMENT_TEAM" *.xcodeproj/project.pbxproj
# ③ 本地有哪些 profile,解一个看内容
ls -lt "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"
security cms -D -i <profile> | plutil -p - | grep -E "TeamIdentifier|ProvisionedDevices|aps-environment|application-identifier"
# ④ 手机 UDID
xcrun devicectl list devices
对照检查:
- ☐ 证书的 Team = 工程的
DEVELOPMENT_TEAM - ☐ 手机的注册 Team = 工程的
DEVELOPMENT_TEAM - ☐ profile 里有这台手机
- ☐ profile 里有当前这把证书
- ☐ profile 有
aps-environment(用到推送时) - ☐ Debug / Release 两个配置的 Team 一致
三句话总结:
already exists on this team八成是设备加错了 Team,不要一上来就怀疑 Apple 后台有僵尸记录- 设备删不掉通常是年度规则(只有本年度新增的设备可删),不是权限问题
- 对齐 Team 能保住自动签名;实在不行用手动 profile,绕开 Xcode 的设备注册逻辑
排查环境:Xcode 26.6 / macOS,双团队(公司 Team + 个人 Team)共用同一个 Apple ID。