...
Back

当审核要一周时,怎么发版

Google Play 的审核现在经常超过七天,而 App Store 的拒因给到 API 的信息远少于网页控制台。这两件事都快不了,所以只能让发布流程把它吸收掉。

当审核要一周时,怎么发版

当审核要一周时,怎么发版 ⏳

这个月 Hacker News 上又冒出那条老抱怨:Google Play 的审核现在动辄超过一周,而从前是几小时。不管这是长期变化还是一次排队积压,有件事变了 —— 审核时长不再是发布末尾的零头,它成了最长的一步,而且是你唯一优化不了的一步。

那就只能让流程把它吸收掉。以下是一个月里在两个商店发版之后,我们认为这句话的具体含义。


真正让你损失一周的是被拒,不是审核

七天通过,是一次七天。七天被拒,是七天,加上你看懂拒因的时间,再加一次七天。问题在于复利,不在于时长。

所以最有杠杆的事不是"早点提交",而是"别被拒",而失败模式无聊地一致:

  • 某个你读不懂的语言里元数据不全。 我们有一次 tvOS 提交被打回,API 只给了一条泛泛的错误。网页控制台最终列出了真正的原因:繁体中文的描述、关键词和支持网址缺失,简体中文的描述也缺。提交接口知道这些,它只是不说。
  • 背书不了的权限。 申请了受限权限却没有描述文件授予,会在很晚才被抓到,而且解释得很糟。
  • 审核员走不通的体验路径。 如果你的应用需要审核员没有的凭据,你就得有一个不联网、不登录也能跑的演示模式,并且在审核备注里写明。

去控制台读拒因,别只看 API

这是我们学到的最有用的一条操作习惯。

App Store Connect 的 API 会丢给你一个 409 或 500,配一句什么都可能的说明。同一次提交,网页界面会把真正缺失的字段逐条列出来。如果你在自动化提交 —— 你应该这么做,API 比点鼠标好太多 —— 那就自动化提交,然后打开控制台读失败。这两个界面承载的信息不一样,而信息全的那个恰好不是你脚本化的那个。

历史上的失败值得直接拉日志:

xcrun notarytool log <submission-id> \
  --key ./AuthKey_XXXXXXXX.p8 --key-id XXXXXXXX --issuer <issuer-uuid>

我们正是用这条命令查清了几个月前一个 DMG 为什么公证失败。答案 —— 内置的一个助手程序没用 Developer ID 证书签名、缺安全时间戳、还带着 get-task-allow —— 一直躺在日志里,而且只躺在日志里。


把产物和公告解耦

如果审核要一周,那"发版"和"宣布"就不能是同一个事件。

把流程安排成:产物在任何外部的人需要知道之前几天,就已经是最终态、可审核的。这意味着:

  • 在审的那个版本就是你打算发的版本,不是打算替换的占位。每替换一次,计时重来。
  • Google Play 上尤其要注意:提交新变更会取消并重启正在进行的审核 —— 而且通过 API 做这件事时是静默的。你在审核期间推更新,并没有加速任何事,只是把已经服完的天数扔掉了。
  • 发布说明、截图、商店文案都是产物的一部分。提交之后再补,等于在改正在被审的东西。

保留一条你自己控制的通道

对审核时长最有力的结构性回答,是别让通往用户的每一条路都经过一个队列。

对桌面软件,这意味着在商店版之外还有一个签名并公证过的直接下载。它确实更麻烦 —— 代码签名、公证、装订票据、托管、更新分发,而且平台差异是真实的。但当商店版卡在一周审核里时,直接下载版就是"我们的用户已经拿到修复"和"我们的用户下周四能拿到修复"之间的区别。

这不是反对商店。分发、发现、支付和信任都实实在在有价值,值得那个队列。这是反对只有一扇门。


我们改了什么

三件事,都是流程而非代码:

  1. 提交成品。 商店列表声明的每一种语言,元数据、截图和备注都齐了,构建才上传。
  2. 把拒因当成控制台的活。 自动化提交,在网页界面读失败,并把公证日志那条命令放在手边备查。
  3. 绝不碰在审的东西。 尤其是 Play,那里的重启是静默的。

这些都不会让审核变快。它们让那一周只花一次。