关于 appstore-review
面向 iOS 开发者的 App Store 审核准备审计技能,检查代码、权限、隐私和提交资料,并按 PASS、WARN 或 FAIL 汇总结果。
主要功能
- 01代码与权限检查
- 02隐私清单和数据审计
- 03订阅与 IAP 检查
- 04App Store 元数据清单
- 05PASS、WARN、FAIL 结果报告
适用场景
- 01提交前检查 iOS 应用
- 02核对订阅页面披露信息
- 03审计隐私声明与数据使用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ 3paws-ai/ mobile-ai-skills --skill appstore-review安装后在 Claude Code 中输入/appstore-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/appstore-review-ref.mdsetup-guide.md详细介绍
App Store 审核就绪情况审计
目的
在提交前,发现所有可能导致 App Store 警告或拒绝的问题。此技能执行双轨审计:代码/权限和提交元数据。审计顺序按照拒绝频率排列(风险最高的在前),依据 Apple 2024 年《透明度报告》数据。
参考文件:references/appstore-review-ref.md 包含支撑每项检查的 Apple 文档、WWDC 会议和社区资源的完整目录。
如何运行审计
调用时,按顺序执行以下所有部分。对于每项检查:
- 检查项目中的相关文件/配置
- 用一行说明报告 PASS、WARN 或 FAIL
- 最后生成包含所有结果的汇总表
不要跳过任何部分。不要询问用户要运行哪些部分——全部执行。
轨道 1 — 代码与权限审计
1.1 App 完整性(指南 2.1)— 首要拒绝原因
这占所有未解决拒绝的 40% 以上。
- App 在全新安装后可以启动且不会崩溃
- UI 中任何位置都没有占位文本或 Lorem Ipsum(搜索所有
.swift文件和资源目录) - 没有表明尚未完成、且用户可见的 TODO/FIXME/HACK 注释
- 所有导航路径均可正常使用——没有无法继续的屏幕或未实现的按钮
- 所有 URL(支持、隐私政策、条款)均有效且可正常加载
- 登录/引导流程可无错误地完成
- 深层链接和通用链接可正确解析(如适用)
- App 可在飞行模式下运行,或能妥善处理无网络状态
1.2 隐私清单(ITMS-91053 / ITMS-91061)— 自动拒绝
自 2024 年 5 月 1 日起强制执行。缺少声明会在人工审核前导致拒绝。
- App 目标中存在
PrivacyInfo.xcprivacy - 已检查是否使用以下五类必需理由 API:
NSPrivacyAccessedAPICategoryFileTimestamp—creationDate、modificationDate、stat()NSPrivacyAccessedAPICategorySystemBootTime—systemUptime、mach_absolute_time()NSPrivacyAccessedAPICategoryDiskSpace—volumeAvailableCapacityKey、NSFileSystemFreeSizeNSPrivacyAccessedAPICategoryActiveKeyboards—UITextInputMode.activeInputModesNSPrivacyAccessedAPICategoryUserDefaults—UserDefaults
- 每项已使用的必需理由 API 都有相应声明,并包含获批的理由代码
-
NSPrivacyCollectedDataTypes准确反映 App 收集的所有数据 -
NSPrivacyTracking设置正确(仅在使用 IDFA/ATT 时设为true) - Apple 列表中的第三方 SDK 均包含各自的隐私清单
- 通过 Xcode Organizer 生成隐私报告,以交叉核对声明
1.3 订阅与 IAP 合规性(指南 3.1.1 / 3.1.2)
订阅类应用的第二高风险领域。
付费墙 UI——必需的披露信息(指南 3.1.2(c) + 附表 2 §3.8(b)):
- 显示订阅名称和时长
- 完整续订价格是最醒目的价格信息(而非月均价格)
- 显示免费试用时长和试用后的价格(如适用)
- 提供可点按且有效的《使用条款》链接
- 提供可点按且有效的《隐私政策》链接
- 可访问“恢复购买”按钮或机制(指南 3.1.1)
- 不得使用暗黑模式设计:不得制造虚假紧迫感、隐藏年费价格,或在未明确披露的情况下预选价格较高的选项
- 显示订阅自动续订说明(例如,“除非至少在当前周期结束前 24 小时取消,否则订阅将自动续订”)
- 提供取消/管理订阅的说明(或使用
AppStore.showManageSubscriptions(in:))
**注意:**仅在应用内披露并不足够。第 2.1 节会检查《使用条款》和《隐私政策》链接是否也显示在 App Store Connect 中的 App Store 描述或 EULA 栏位——Apple 要求两处都提供。
StoreKit 实现:
- 使用 StoreKit 2(而非已弃用的 StoreKit 1 /
SKPaymentQueue) - 已验证交易(通过 JWS 验证或由 RevenueCat 处理)
- 购买、恢复和订阅到期后,权益均能正确更新
- 已实现宽限期处理(如已在 App Store Connect 中启用)
- 应用内的沙盒购买功能正常
App Store Connect 配置:
- IAP 产品处于“Prepare for Submission”状态,并已附加到审核提交(该提交中的状态为“Ready for Review”),或已获“Approved”——独立的“Ready to Submit”这一术语早于当前的审核提交模式
- IAP App Review 截图是实际购买界面的原始截屏,尺寸须符合应用支持的设备截图尺寸(例如,6.9" = 1320×2868)——不得使用 1024×1024(那是相邻的推广图像栏位,不能作为审核截图,否则会被拒)
- 每个 IAP 都有审核截图(同一张展示多个 SKU 的购买界面截图可用于其中每个 SKU)
- 每个 IAP 的审核备注:如何在应用内找到购买入口、购买内容解锁什么、如何恢复购买,以及无需账户时的说明
- 正确配置订阅组
- 为所有必需地区设置价格
**提交编排:**审核提交的组装规则(哪些产品必须随版本一同提交,以及何时提交)见第 2.7 节——首次提交 IAP 时,实际提交曾因此受阻。
1.4 隐私与数据处理(指南 5.1)
- 已在 App Store Connect 中设置《隐私政策》URL,且可访问
- 可在应用内访问《隐私政策》URL
- App Store Connect 中的 App 隐私营养标签与实际数据收集情况相符
- 如果应用使用 IDFA:已实现 ATT 提示(
ATTrackingManager.requestTrackingAuthorization) - 如果应用使用第三方 AI:已就数据共享征得明确同意(指南 5.1.2(i),2025 年 11 月起执行)
- 如果应用支持创建账户,则提供账户删除选项(指南 5.1.1(v))
权限请求前的预先说明文案(指南 5.1.1(iv)):
- 检查引导/预先说明视图中,在系统权限提示出现之前显示的按钮;若按钮标注为“启用……”“允许……”或“打开……”,则必须改为中性措辞(“继续”/“下一步”);预先替用户回答系统提示的按钮会导致违反 5.1.1(iv) 而被拒
- 预先说明屏幕上的正文解释文案没有问题,且建议提供——只有按钮标签必须保持中性
- 引导用户前往“设置”的拒绝权限后屏幕不受此限制(可以显示“打开设置”)
1.4b 面部与生物识别数据(指南 2.1 / 5.1)
如果应用使用了 Vision / 人脸检测 API,即使完全在设备端处理且不收集任何数据,也要预期审核期间会收到 Apple 的标准六项面部数据问卷。这六项问题涉及:
- 收集哪些面部数据以及如何使用
- 是否与第三方共享面部数据(以及共享对象)
- 面部数据的保留时长
- 是否以及如何删除面部数据
- 面部数据的存储位置(设备端还是服务器)
- 隐私政策中披露相关信息的位置(Apple 会要求引用具体文本)
- 隐私政策中有明确且可引用的 “面部数据” 专门章节,涵盖收集、使用、共享、保留、删除和存储;泛泛提及“照片”无法满足审核人员的要求
- 该章节如实列出二进制文件中的所有人脸检测调用位置;Apple 会根据实际 API 使用情况核实声明(遗漏一处导出时的人脸检测就足以导致审核失败)
- 不使用人脸特征码 / 人脸识别 API;或者,如果使用了,则记录符合 ADPLA §3.3.3(C)/(K) 的情况
- 第三方 AI 处理方关于数据保留的声明与其自身记录在案的保留政策一致;只有在确实签订了合同约束的零数据保留(ZDR)协议时,才能声明零保留
- 将针对六项标准问题预先拟好的答复与提交元数据一并保存(注意:App Store Connect 的回复框上限为 4,000 个字符,因此较长的政策引用必须摘录)
1.5 App Transport Security
- Info.plist 中没有
NSAllowsArbitraryLoads = YES(除非有合理说明) - 所有网络连接均使用 HTTPS / TLS 1.2+
- 如果通过
NSExceptionDomains设置了域名例外,必须为每项例外记录合理说明
1.6 出口合规
- 在 Info.plist 中设置
ITSAppUsesNonExemptEncryption - 如果仅使用标准 HTTPS(URLSession),值为
NO(豁免) - 如果使用自定义加密,值为
YES,并备有 CCATS/ERN 文档
1.7 权限与功能
- 仅包含必需的权限(没有未使用的功能)
- App ID 为显式 ID(非通配符)——IAP 所必需
- 在 Signing & Capabilities 中启用 In-App Purchase 功能
- 仅在实现了推送功能时才包含 Push Notification 权限
- 除非使用 Apple Pay,否则不要添加
com.apple.developer.in-app-payments(这不是 IAP 权限)
平台目标(影响截图要求——参见 2.2):
-
TARGETED_DEVICE_FAMILY与产品定位一致(仅限 iPhone 时设为1;Xcode 模板默认值"1,2"表示支持 iPad,并会触发 App Store Connect 的 iPad 截图要求) - 有意设置
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD、Mac Catalyst 和其他专为特定平台设计的目标,而非沿用模板默认值 - 注意:即使 iPad 不是声明的目标平台,审核期间仍可能在 iPad 的兼容模式下运行应用
1.8 代码质量检查项
- 生产代码中没有
print()语句(使用os.Logger) - 测试代码之外没有强制解包(
!) - 源代码中没有硬编码的 API 密钥、机密信息或令牌
- 没有引用内部 / 调试 URL、测试服务器或预发布环境端点
- 没有会在发布版本中暴露测试界面的
#if DEBUG代码块
路线 2 — 提交元数据检查清单
2.0 一次性应用信息门槛
在完成这些应用级设置之前,添加以供审核按钮会被静默禁用—— 这类门槛与年龄分级问卷(第 2.5 节)相同。
- 在“应用信息”页面声明内容权利信息(应用是否包含第三方内容:是或否;答案因应用而异:通常仅包含用户生成内容时选“否”,展示外部 / 网页内容时选“是”)
- 首次点击添加以供审核之前,填写完整所有必填的应用信息字段
2.1 App Store Connect 元数据
- App 名称:不超过 30 个字符,不堆砌关键词
- 副标题:不超过 30 个字符
- 描述:首行吸引用户,突出益处而非功能,不含占位文本
- 关键词:不超过 100 个字符,以逗号分隔,逗号后不加空格,且不与标题中的词重复
- 推广文本:已设置(无需发布新版本即可编辑)
- 更新内容:使用通俗易懂的语言撰写,侧重用户获益
- 支持 URL:已设置且可正常加载
- 隐私政策 URL:已设置且可正常加载
- 如果 App 提供订阅:在 App 描述中添加使用条款(EULA)链接,或在 App Store Connect 中设置自定义 EULA
- 如果 App 提供订阅:在 App 描述中添加隐私政策链接
- 如果 App 提供订阅:在 App 描述中说明自动续订信息(价格、时长、取消方式)
- 版权信息:已设置当前年份和正确的实体名称
- 已正确设置主要类别和可选的次要类别
2.2 屏幕截图和预览
- 至少设置一张符合精确 iPhone 上传槽位规格的屏幕截图:6.9" = 1320×2868 或 6.5" = 1284×2778;其他实际设备尺寸(例如 6.3")不是有效的上传槽位
- 如果是通用 App,提供 iPad 屏幕截图
- 如果除了 iPhone 外还要求提供屏幕截图(iPad、visionOS),则应重新审核目标声明的目的地——参见第 1.7 节(
TARGETED_DEVICE_FAMILY/ 为默认设备设计通常是原因) - 屏幕截图为 JPEG 或 PNG 格式
- 不含占位或明显伪造的屏幕截图
- App 预览不超过 30 秒,编码格式为 H.264 或 ProRes 422(如果使用)
- 屏幕截图展示实际 App 界面(不误导用户)
2.3 App 图标
- 已提供 1024x1024 的 App Store 图标
- 图标不包含透明度或 Alpha 通道
- 图标与其他 App 的图标不同
- App 内的图标与 App Store 图标一致
2.4 版本和构建
- 根据需要递增版本号(遵循语义化版本规范)
- 构建号比上次上传时递增
- App 目标和扩展目标(如有)均具有匹配的版本号和构建号
- 使用当前要求的 SDK 版本构建
2.5 年龄分级
- 已在 App Store Connect 中完成年龄分级问卷
- 分级符合实际内容(尤其是适用时的 AI/聊天机器人内容)
- 如果适用扩展年龄分级(13+/16+/18+):已于 2026 年 1 月 31 日截止日期前更新问卷回答
2.6 审核备注
- 如果 App 需要登录:在审核备注中提供演示凭据
- 如果 App 包含特殊流程(订阅、硬件功能):提供相关说明
- 如果 App 使用设备端 AI:注明设备/操作系统要求
- 如果 App 提供订阅:在审核备注中说明可在何处查看 App 内订阅披露信息(付费墙位置、设置等)
- 审核人员的联系信息为最新信息
2.7 审核提交组装(指南 2.1(b))
App Store Connect 会将一个版本及其 IAP 归入同一个审核提交。 以下拓扑规则在 UI 中并不明显,会导致 2.1(b) 应用完整性审核被拒:
- 应用首次提交的 IAP 必须与应用版本附加到同一个审核提交中。 如果只提交版本,而产品仍处于“准备提交”状态,就会触发 2.1(b) 拒绝(“应用包含对某个产品的引用,但关联的 App 内购买产品尚未提交”)——Apple 给出的补救办法是提交 IAP 以及一个新的二进制文件。
- 每个平台同一时间只能有一个审核提交。 当某个版本处于等待审核/审核中状态时,送审的 IAP 会进入单独的草稿提交,该提交无法提交,也不会自动随版本一起提交。如果版本提交已封存,就没有 UI 操作路径可以将它们附加进去——只能等待被拒或获批。
检查项:
- 二进制文件引用的所有 IAP 产品都已附加到与版本相同的审核提交中(而非仅处于“就绪”状态)
- 首次提交 IAP:确认其在点击版本的“添加以供审核”之前,已位于该版本的提交中
- 如果版本已在审核中,但未包含 IAP:预期会收到 2.1(b) 拒绝——提前准备一个新的构建号
- 发布时机:已获批但 IAP 未获批的版本上线后,付费墙将无法加载产品——如有需要,在 IAP 获批前暂缓手动发布
输出格式
完成所有检查后,生成以下摘要:
## App Store Review Audit — [App Name]
Date: [YYYY-MM-DD]
### Results
| # | Check | Status | Notes |
|---|-------|--------|-------|
| 1.1 | App Completeness | PASS/WARN/FAIL | ... |
| 1.2 | Privacy Manifest | PASS/WARN/FAIL | ... |
| ... | ... | ... | ... |
### Critical Issues (FAIL — must fix before submission)
- [list]
### Warnings (WARN — should fix, risk of rejection)
- [list]
### Recommendations
- [list]
如果没有 FAIL 项,请写明:“未发现阻塞问题。可以提交。”
要求变更时
Apple 会在以下地址公布执行期限:
https://developer.apple.com/news/upcoming-requirements/
如果用户提到具体期限或新要求,请对照
references/appstore-review-ref.md 第 8 节,查看最新跟踪的变更。