TestFlight build 过期:90 天硬期限 + 替换流程

测试员看到 "This beta has expired",或 App Store Connect 中 build 标记 Expired。

测试员发消息:“你这 beta 打不开了,提示 ‘This beta has expired’。” 你打开 App Store Connect → TestFlight → Builds,看到那个跑了两个月的 build 现在显示 Expired。部分测试员还能启动(设备上缓存了几天,取决于 iOS 版本),但新安装和大部分老安装都被挡。整个外部测试周期就此暂停,你也无法”延长”过期的 build。

TestFlight build 有从上传日起 90 天的固定有效期。Apple 强制执行,无账号级例外,无延期机制。修法不是把死的 build 救回来——而是上传一个版本号相同或更高的新 build 替换掉它,在测试员的 TestFlight App 里挤掉旧的。

常见原因

按命中率排序。

1. Build 到了 90 天 TestFlight 生命周期

90 天时钟从上传起,不是从第一次安装起。90 天后 Apple 在 App Store Connect 标 build 为 Expired,TestFlight App 拒绝启动并提示 “This beta has expired”。没有任何延期机制。

如何判断:App Store Connect → TestFlight → Builds 看 build 上传日。85+ 天前的就快过期或已过期。

2. 过期前没传新 build

你为一个长跑 beta 只传过一个 build 从不轮换。第 91 天 build 过期,测试员被锁出去,你手头没有备用 build。

如何判断:TestFlight Builds 标签下数 “可用” build 数量。只有一个还很旧就有风险。

3. 留着旧 build 同时撤回了新 build

你传了新 build 挂给测试员后发现回归 bug 撤了。测试员退回到老 build,老 build 在你修 bug 时过期。

如何判断:Activity 日志里看最近的 “withdrawn” 动作。当前唯一 “active” build 超过 60 天就有轮换缺口。

4. 新 build 传了但没挂上 group

你传了新 build 处理完了,Builds 里显示 “Ready to Submit”,但忘了加进外部测试 group 或发给内部测试员。旧的过期了,测试员看不见新的。

如何判断:TestFlight → 你的 group,查挂的 build 列表。最新 build 没在 group 里就要挂上。

5. 新 build 在等 Beta App Review

你及时上传了,但新 build 在 Beta App Review 排队。等的时候旧 build 过期,测试员两个都看不到。

如何判断:新 build 状态 “Waiting for Beta App Review”。用内部测试做兜底,或者等 Beta 审核。

动手前先确认

  • 确认 build 真的是过期不是暂停——Apple 显示不同状态。
  • 决定上一个全新版本还是只 bump build 号——都能替换过期 build。
  • 改之前把当前 archive 备份本地。
  • 弄清你这个 App 历来 Beta 轮换节奏是否合规,预防比修复重要。

需要收集的信息

  • 过期 build 的上传日期(90 天计算用)。
  • 过期 build 的版本(CFBundleShortVersionString)和 build 号(CFBundleVersion)。
  • 任何 pending build 的状态(Processing、Waiting for Review 等)。
  • 过期 build 和 pending build 各自的 group 挂载状态。
  • 测试员投诉时间戳(如果你要沟通修复时间)。

最短修复路径

Step 1:找对 “下一个” build

App Store Connect → TestFlight → Builds 找:

  • 已处理且版本 ≥ 过期 build 版本、build 号更高的。
  • 没有就要上新的。

不能复活过期 build,只能用替换。

Step 2:打新 archive

Xcode:

  • 递增 CFBundleVersion(如 4748)——必须,因为 47 还在 Apple 记录里。
  • 这是真功能更新就一并 bump CFBundleShortVersionString
  • Product → Clean Build Folder。
  • Product → Archive(Generic iOS Device)。

或用 xcodebuild:

agvtool next-version -all  # bump build 号
xcodebuild -workspace Acme.xcworkspace -scheme Acme \
  -archivePath build/Acme.xcarchive archive
xcodebuild -exportArchive -archivePath build/Acme.xcarchive \
  -exportPath build/ipa -exportOptionsPlist exportOptions.plist
xcrun altool --upload-app -f build/ipa/Acme.ipa \
  -t ios -u "$ASC_USER" -p "@keychain:ASC_PASSWORD"

Step 3:等处理完成

Apple 处理 build(典型 10-60 分钟)。状态走 “Processing” → “Ready to Submit”(挂上并审核通过后切 “Ready to Test”)。

# 可选:用 App Store Connect API 监控
curl -H "Authorization: Bearer $JWT" \
  "https://api.appstoreconnect.apple.com/v1/builds?filter[app]=$APP_ID&sort=-uploadedDate" \
  | jq '.data[0].attributes.processingState'

Step 4:(外部测试)提 Beta App Review

如果是新版本(如 2.8 vs 过期的 2.7),新版本第一个 build 要 Beta App Review。同版本 + 新 build 号通常不用重审(自动批)。

App Store Connect → TestFlight → External Testing → 你的 group → Build → Submit for Beta App Review。

Step 5:挂上测试组

变 Ready to Test 后:

  • TestFlight → External Testing → 你的 group → ”+” → 选新 build。
  • TestFlight → Internal Testing → ”+” → 选新 build(不用审核)。

Step 6:通知测试员

App Store Connect → TestFlight → External Testing → 你的 group → “Notify Testers”。会给测试员发邮件附深链跳更新。

写一份测试员看的发布说明,这就是 “What’s New for testers” 字段。把替换专属信息写上(如 “请更新——上一个 build 已过期”)。

怎么确认已经修好

  • 过期 build 状态保持 “Expired”,新 build 显示 “Ready to Test” 或 “Available”。
  • 通过 TestFlight 更新的测试员看到新 build 的发布说明。
  • 干净设备用 TestFlight 邀请链接冷装拿到的就是新 build。
  • 新 build 的到期日(App Store Connect 可见)是上传日 +90 天。

如果还是没修好

  1. 新 build 测试员看不到就核查它是不是挂上了对的 group 且 Ready to Test(不是还在 Waiting for Review)。
  2. 让测试员强刷 TestFlight:杀进程重开;或在 TestFlight 登出再登入。
  3. 检查测试员是不是在没挂新 build 的 group 里;他们还在看老(过期)build。
  4. Beta 审核异常慢就看 Beta App Review 太慢

预防建议

  • 任何长跑 beta 在上传日 +80 天加日历提醒。
  • 维护”轮换”节奏:至少每 60 天传一个新 TestFlight build,即使代码改动很小。
  • 活跃外部 group 始终挂着至少一个 60 天内的 build。
  • 每轮测试都 bump build 号,让向前滚成为机械操作。
  • BETA.md 里记录 TestFlight 轮换流程,责任不只压在一个人身上。

相关阅读

标签: #排查 #App Store #App 审核 #TestFlight #Build 过期