2026年8月注:本文来自较早的版本,描述的是当时的订阅层级。AlcoLog 在 v1.2.0 中把 Pro 并入了 Premium,所以现在只有一个付费层级。合并过程中没有丢失任何功能,原有的 Pro 用户已免费升级到 Premium。

如果你即将发布一款 v1.0 的 iOS 应用,而它带有订阅、App 内购买、Watch 配套应用、小组件,或者任何与健康沾边的定位,那么 App Review 的难度会比文档暗示的更大。本文记录了一次上架周期(五天内被拒四次,五位审核员,同一个二进制文件),以及让这个周期得以撑过去的规律。我之所以分享,是因为这段经历是认真做独立应用时记录最少的环节之一,而有据可查的版本(WWDC 讲座、审核指南页面、开发者论坛)与日常实际情况并不相符。

如果你正处在审核周期当中,想找具体的修复办法,可以直接跳到“提交前应当修复的问题”和“值得了解的规律”。如果想了解来龙去脉,个人时间线在后半部分。

# 提交前应当修复的问题

以下是四次被拒中出现过的问题。如果提前修好,一款带订阅的敏感类别 v1.0 应用可能被拒的大部分地方就都排除了。

# 订阅付费墙上的价格显示层级

Apple 的《人机界面指南》对订阅价格的呈现方式有明确要求:实际扣费金额必须是最醒目的价格元素。营销直觉(让折扣看起来像是赚到了)在这里是错误的直觉,合规直觉(让扣费金额在排版上最突出)才是对的。

落到实际上就是:常规价格应当是字号最大、字重最粗的元素。首期价格或折扣价格应当更小,并明确标注“首期:”。不要在小标记里使用百分比徽章(用“首发优惠”,而不是“25% OFF”)。在这一点上,不同审核员对 3.1.2© 付款与订阅条款的执行是一致的。

# 明确的数据删除途径

即使你所谓的“账户”只是一个用户自愿开启的匿名标识符,Apple 的 5.1.1(v) 条款也要求提供有标签、看得见、立即生效的删除途径。把“关闭开关”当作隐含的删除,在开发者看来似乎合规,但满足不了当前的执行标准。

从第一个版本起,就在隐私或设置界面里放一个明确的“删除我的数据”按钮,并加上确认提示。确保周围的说明文字描述的是实际的删除行为,而不是一个你打算以后再改的占位时间表。

# 检查 Info.plist 中的残留声明

后台模式、后台获取、位置权限、HealthKit 声明以及类似的 Info.plist 条目,可能在代码库不断迭代的过程中闲置好几个月。一旦它们与实际功能对不上,就会被标记出来。这里对 2.5.4 软件要求条款的执行是机械式的,而且毫不含糊。

具体来说:任何 UIBackgroundModes 条目都必须对应一个真正用到它的功能。如果你的应用把“location”声明为后台模式,但你从不使用持续的后台定位,并且设置了 allowsBackgroundLocationUpdates = false,那就删掉这条声明。区域监测并不需要它。这项检查只需要十分钟,却能省掉一轮被拒。

# App Store 元数据中可用的使用条款链接

App Store Connect 中的隐私政策字段大家都很熟悉,使用条款的要求却不那么为人所知。如果你使用的是 Apple 标准 EULA,就在 App 描述中加入使用条款的链接。如果你使用的是自定义 EULA,就把它填进 App Store Connect 的自定义 EULA 字段。

条款页面本身应当披露所有付费产品,包括订阅时长、价格和续订机制。大多数团队把这些内容分散在不同页面,或者埋在隐私政策里。把它们整合到一个审核员两分钟就能读完的条款页面里。

# App 预览视频:使用原始录屏

3D 手机样机、设备边框和风格化的营销合成画面,在 2.3.4 准确元数据条款下都取决于审核员的判断。公开的指南页面并没有明确禁止设备边框,但审核员所依据的内部培训材料似乎是禁止的。原生分辨率的纯录屏则毫无疑问是安全的。

把营销包装留给你自己的网站、社交媒体和 Reddit。App 预览位置放录屏就好。“精致样机预览”和“原始录屏预览”之间的转化率差别很小,风险的降低却很大。

# 在 App Review 备注中写明 App 内购买的操作路径

审核员对每个应用的时间预算是5到15分钟。他们不一定能找到这个版本附带的每一个 App 内购买项目。如果你的 App 内购买项目要通过应用中不同的路径才能找到(不同的付费墙、不同的卡片、更深的层级),就在 App Review 备注中为每一个项目写清逐步点击的导航路径。

行之有效的格式:

Premium 订阅和终身版 App 内购买:「设置」标签页 > Premium 卡片 >「获取 Premium」按钮 > Premium 升级页面 Pro 订阅和终身版 App 内购买:「设置」标签页 > Pro 卡片 >「获取 Pro」按钮 消耗型小费项目:「设置」标签页 > 向下滚动越过各层级卡片 > 小费卡片 >「显示小费选项」

这听起来有些过头。但它能避免一种特定的被拒周期(指南 2.1(b) 需要更多信息),否则你要为此多搭上一天。

# 在提交日期和对外承诺的发布日期之间留出缓冲

对于敏感类别中带订阅的 v1.0 提交,首次提交与对外承诺的发布日期之间至少要留出七个自然日。只要你回复及时,每一轮被拒周期大约需要24小时。对于敏感类别的 v1.0 提交,四轮被拒是一个现实的最坏情况。

如果你的发布日期已经对外承诺(配置了预订、安排了 App 内活动、订好了营销推广、联系了记者),七天缓冲是最低限度,十天会更从容。少于七天,你就有可能因为一次程序性的被拒而错过日期。

# 值得了解的规律

以下是身处这个周期中的一些观察,从文档里看不出来。

# 每次被拒发现的问题都不一样

四次被拒标记出的问题互不重叠。每一位审核员都能看到前一位审核员已经放行的所有界面。第一位审核员标记了元数据中的 EULA 链接。第二位在同一个二进制文件里标记了三个不同的问题(后台模式、价格显示、删除按钮)。第三位标记了一项营销素材。第四位提了一个关于导航的问题。

这不是漏洞,而是 App Review 结构本身的特点。审核似乎是按问题进行的,而不是按应用进行的。审核员在时间预算内发现第一个重大问题就会停下。他们不需要做详尽的检查,系统也不会给前一位审核员接受过的部分标上“已放行”的状态。这种结构优先考虑的是机构的处理量,而不是开发者的体验。

这意味着:任何一次审核都不可能给你一份全面的检查结果。你只能得到当前这位审核员在其时间窗口内发现的问题,而且必须接受下一位审核员可能在下一轮中独立发现其他任何问题。

# 每次被拒的范围往往比上一次小

这只是一个大致的规律,并不保证。第一次被拒往往是实质性的(缺少某项要求,或者架构上的问题)。第二次仍然是实质性的,但更像是对照清单。第三次会偏向边缘的元数据。第四次有时根本不是被拒,而是一个程序性的提问。

原因并不是应用每一轮都在“变得更好”,而是随着之前被标记的问题得到修复、之前已放行的内容不再属于审核范围,二进制文件和元数据中可供审核的部分每一轮都在缩小。审核员们各自在耗尽可用的清单项目,所以越往后的审核能发现的东西越少。

身处周期之中时,这个规律会让人安心,但不要把宝押在它上面。后期的审核员仍然可能发现早先审核员漏掉的实质性问题。

# 审核员的细致程度差别很大

同一个二进制文件的四次审核,每位审核员发现的内容差别很大。有人发现了三个问题,有人只发现一个边缘问题,还有一位提的问题,只要在应用第二个标签页里轻点一张卡片就能找到答案。

每一轮由哪位审核员接手你的提交,你完全无法左右。要为这种差异做好准备。不要以为下一轮会比上一轮更细致或更宽松。它们是从一个分布很广的总体中独立抽取的样本。

# Beta App Review 通过并不能预示正式 App Review 会通过

这两条流程由不同的团队负责,标准也不同。同样的功能在 Beta 审核中通过、却在正式审核中被标记,这并不矛盾,它们本来就是两套不同的审核流程。

如果你用 TestFlight 来确认应用是否已经为正式审核做好准备,那你看错了信号。TestFlight 能发现构建是否有效以及基本的合规问题,正式的 App Review 则覆盖全部执行范围。两者不能互相替代。

# 敏感类别的审查因素会叠加

订阅,尤其是带有首期优惠价格或试用的订阅,会自动触发 3.1.2 条款的审查。与健康相关的类别(酒精、健身、心理健康、睡眠)会让审核员关注 1.4.1 条款下的医疗声明问题。涉及隐私的功能(位置、HealthKit、匿名标识符)会引来 5.1.1 条款的审查。首个版本的 v1.0 提交会触发全面审核。与发布日期绑定的 App 内活动会引来对元数据的审查。

每一项单独来看都能应付,但它们是成倍叠加的。一次在敏感类别中带有订阅、多个平台和 App 内活动的认真发布,会让所有因素同时生效。而一个没有 App 内购买、只有单一界面的免费工具,两分钟就能通过。你的审核体验有多难,与你这次发布有多认真、覆盖面有多广相关,而与你的应用质量无关。

# 文档与执行并不总是完全一致

被拒理由引用的指导内容,未必明确出现在所链接的公开页面上。审核员依据的是内部培训材料,它与公开的审核指南有重叠,但并不完全相同。如果你遇到与公开文档不符的被拒,可以礼貌地提出异议。有时会被撤回,有时不会。

提出异议时,请在解决方案中心以书面形式进行,用一段结构清晰的文字引用公开的指南内容,并询问具体适用的是哪一条款。措辞中不要带情绪。审核员是在有限的时间预算内阅读你的回复的,会被认真阅读的,是那种尊重这一点的回复。

# 如何建设性地回应被拒

关于在解决方案中心来回沟通的几点实用建议。

# 尽量当天回复

走出这个周期最快的方法,就是让周期持续运转。每次你回复时,被拒周期的计时都会重新开始。当天回复,当周就能解决;隔几天才回复,周期就会相应拉长。

这要求你的团队能够快速交付修复。对独立开发者来说,这往往意味着要把提交之后那几天的日程清空。提交窗口期不能当成后台任务来对待。

# 把修复打包成一次重新提交

如果一次被拒标记了三个问题,就把三个都修好再重新提交。不要发“修好了三个中的两个,第三个正在处理”这样的回复。下一位审核员会发现完全不同的问题;只修了一部分的回复只会让队列里再多一轮周期。

# 附上验证修复的录屏

对于任何不那么简单的修复,附上一段30秒的录屏,展示修复后的效果:删除流程、修正后的价格显示、新的导航路径。如果审核员不必自己去找就能看到修复,下一轮放行这个问题的可能性就更大。

# 在回复中请求全面审核

礼貌地请求在当前这一轮中把所有剩余问题一并提出,而不是分散到更多轮次里,这是合理的。它不一定奏效,但偶尔会。措辞很重要:“对于目前提出的每一个问题,我们都已及时且真诚地处理。希望这一轮能对照所有适用的指南进行全面审核,以尽量减少后续的周期。”

这样一来,审核员的下一次回复要么放行应用,要么提出所有剩余的问题。两种结果都比又一次只针对单个问题的被拒要好。

# 把每一轮都当作独立的审核

人们很容易以为下一位审核员读过前一位的备注。他们多半没读过。解决方案中心的每一条回复都应当自成一体,为一个没看过之前对话的人总结提交的现状。

这意味着各轮之间少量的重复是必要的。对第一位审核员有效的详细 App Review 备注,应当为第三位审核员重新附上或重新说明。不要指望机构会记得。

# 个人时间线

作为背景,下面是这五天实际的经过。

我在周六下午提交了第22个构建版本。这次提交包括4个自动续订订阅、2个非消耗型终身版 App 内购买项目、5个消耗型小费项目、App 描述、截图、App 预览视频、一个与发布周绑定的 App 内活动,以及在175个国家和地区为发布日配置的预订。

在此之前的六周里,我系统地排除了所有能预料到的问题。App Review 备注已经写好,用审核员容易理解的方式解释了应用中最可能受到审查的部分。DSA 交易者信息在一周前获批。App 隐私“营养标签”已经上线。Beta App Review 已经放行了好几个构建版本。我觉得已经准备好了。

第2天,凌晨5:15:第一次被拒。指南 3.1.2©。App Store 元数据中缺少可用的使用条款链接。当天发布修复(在应用内的升级页面加入条款链接,扩充条款页面以披露所有付费产品,更新 App 描述)。一天一轮。

第4天,下午4:03:第二次被拒。一条消息里有三个问题。指南 2.5.4(UIBackgroundModes 中残留了一条本不该存在的“location”条目)。指南 3.1.2©(首期优惠价格显示得比实际扣费金额更醒目)。指南 5.1.1(v)(匿名标识符的关闭开关需要配一个明确标注的删除按钮)。当天发布修复(删除 Info.plist 条目,颠倒价格层级,增加一个带确认提示的明确的“删除匿名数据”按钮)。一天一轮。

第5天,下午5:05:第三次被拒。指南 2.3.4 准确元数据。App 预览视频用3D手机样机展示了应用的界面。审核员的备注指出,内容没有“充分展示应用的实际使用情况”,并特别点名了设备边框。

难点在于:developer.apple.com/app-store/app-previews/ 上的公开指南页面并没有明确禁止设备边框。最接近的成文规则是“始终保持在应用内”,举的例子是越肩拍摄和与设备的实际交互。两者都不适用。

距离发布只剩四天,而且已经累计延误了四天,我做出了取舍:删除 App 预览视频,好让重新提交不被卡住;礼貌地请求重新考虑,如果我漏看了某个具体的指南条款,请对方指出;并发送了一段礼貌、结构清晰的文字,请求在这一轮把所有剩余问题一并提出。删除 App 预览视频的决定维持不变,重新考虑的请求没有得到直接回复。

第6天,晚上7:23:第四条消息。指南 2.1(b) 需要更多信息。严格来说这不算被拒,而是暂停审核来提一个问题。审核员找不到这个版本附带的两个 App 内购买项目,问应该去哪里找。

他们附上的截图正确显示了第一个付费墙。第二个付费墙就在同一个「设置」界面上,轻点审核员已经成功找到的那张卡片正下方的另一张卡片就能打开。我回复了全部11个 App 内购买项目的明确分步导航说明,一小时内就发了出去。

第7天,晚上8:30:通过。构建版本放行,预订启动。发布周定在5月11日。

这五天很紧张。回头看,没有哪一天是生死攸关的,尽管身处其中时并不这么觉得。累计的延误差点让发布日期泡汤,但最终没有。实际发布的产品和提交前做好的完全一样。为了通过审核,没有删减、修改或推迟任何东西。

# 审核没有标记的内容同样说明问题

在四次审核中,我花最多时间担心的那些部分从来没有被标记过。

习惯评分功能(一个0到100分的评分,由六个加权维度中的加分项和减分项构成)。药物追踪功能(只做记录,不给出任何建议性内容)。隐私模式(没有账户,数据留在设备上,匿名共享需自愿开启并可明确删除)。HealthKit 写入。这些部分是应用中最可能引发健康声明或隐私问题的地方,但在四次审核中一次都没有被标记。四位独立的审核员都看过,也都选择了不标记。

这对做敏感类别应用的开发者意味着:主动披露的工作是有用的。解释方法的 App Review 备注、应用内的免责声明、谨慎的命名选择、App 描述中保守的表述,这些都不光鲜,但全都促成了连续四位审核员选择不标记最具争议的部分。18+ 的年龄分级、首次启动时必须确认的免责声明页面、相关区域中明确写着“我们不提供医疗建议”的文字,全都起了作用。

被标记的反而是程序性和机械性的部分:价格显示层级、后台模式声明、元数据链接是否存在、营销素材的构图、App 内购买是否容易找到。应用中实质性的部分在每一轮都通过了。

# 写给独立开发者的最后几点

还有几点观察,放不进上面的内容里。

你在 App Store 里看到的那些粗糙应用,并没有受到更宽松的对待。它们是多年前标准还比较低的时候获批的,或者根本没有触发你这次认真发布所触发的那些审查因素。这个系统用低审查来回报低投入、低风险的应用。你的投入和用心,正是你的审核更难的原因之一。这并不是对你应用质量的评价。

这个系统的人手配置,并不是为了给你想要的体验。App Review 是一个外包审核员团队。审核员每天要处理几十个应用,每个应用只花几分钟。他们接受的培训是把审核指南当作清单来用,而不是去了解某个应用的具体用户体验。这种共情上的落差是结构性的,不是针对个人的。

独立开发者的经历记录下来,最终会推动改变。过去十年里,Apple 对 App Review 做了实实在在的改进。其中一部分可以追溯到独立开发者持续记录自己的经历,以及由此累积起来的压力。你个人的一次被拒不会让哪位审核员被重新培训,但独立开发者经历的系统性汇总,最终确实会改变机构的做法。

你多半能按原样发布你做出来的产品。我担心可能会被砍掉的每一项功能都完整地发布了。四次被拒的周期在进行时让人觉得生死攸关,但只要我持续清晰地回复,并且在手里留好发布日期的缓冲,实际结果最终都会走向通过。

如果你此刻正处在审核周期中,在解决方案中心熬夜奋战:发布终会到来。继续回复。这个系统不是针对你个人。产品是你的。


本文记录的是 AlcoLog 的上架过程,这是一款 iOS 饮酒记录应用。在经历上述周期之后,AlcoLog 将于2026年5月11日在 App Store 上线。应用可免费使用,并提供可选的 Premium 层级,现已在175个国家和地区开放预订。

如果你是 iOS 开发者,想交流 App Review 的经历,r/iOSProgramming 上的独立 iOS 开发者社区和 Indie Hackers 都是不错的起点。我们每个人把遇到的情况记录得越具体,汇总起来对下一个人就越有用。