关于 app-store-submission-auditor
App Store Submission Auditor 是一项检查项目中 App Store 拒审风险并报告问题与修复建议的技能。它会根据开发者经验、项目技术栈和构建状态调整审核指导。
主要功能
- 01扫描项目文件以查找提交风险
- 02检查权限、账户删除和登录
- 03审查支付、网络设置和隐私披露
- 04检测调试残留和网页包装模式
- 05根据开发者经验和构建状态调整指导
适用场景
- 01在提交 App Store 前检查 iOS 应用
- 02查找与应用功能不匹配的权限说明
- 03检查账户删除和支付流程
- 04为未完成的应用选择审核或构建清单
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ itsncki-design/ app-store-submission-auditor --skill app-store-submission-auditor安装后在 Claude Code 中输入/app-store-submission-auditor确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdconfig.jsonreferences/flutter-patterns.mdfirst-time-dev.md详细介绍
App Store 提交审核器
扫描项目文件夹,查找 App Store 拒审风险。不来回询问——阅读代码, 找出问题并汇报。根据用户的水平和构建状态调整。
首次开发者
如果用户提到“第一个应用”“首次提交”“以前从未提交过”或
“新开发者”→加载 references/first-time-dev.md 并先运行该清单,
然后继续进行下方的完整审核。
配置——扫描前检查
在技能目录中查找 config.json。如果存在,读取其中保存的偏好设置
(技术栈、应用类型、订阅状态、欧盟分发、之前的审核结果)。
如果不存在,则在首次审核后,根据检测到的信息创建:
{
"mode": "vibe_coder",
"stack": "flutter",
"has_subscriptions": true,
"has_social_features": true,
"has_location": true,
"eu_distribution": false,
"first_time_submitter": false,
"last_audit": "2026-03-19",
"issues_fixed": []
}
后续运行时:加载配置,跳过已知内容的重新检测;如果 issues_fixed 已填充, 则注明“上次审核:[date] — 此后你修复了 [N] 个问题。”
注意事项——避免常见误报
以下是 Claude 执行此项审核时最常犯的错误。 标记问题前先检查这些事项。
1. Stripe 用于实体商品没有问题 只有在 Stripe/PayPal 用于数字商品或功能时,才将其标记为违规。 Stripe 用于实体商品交换、市场托管或现实世界服务 = 不违规。 只有在积分/付款解锁应用内数字功能时才标记。
2. WebView 用于帮助/法律内容没有问题 只有当 WebView 是主要 UI 时,才将其标记为网页封装。WebView 在其他部分为原生的应用中加载服务条款页面、帮助文章或外部链接,没有问题,且符合预期。只有在原生屏幕少于约 5 个,且 WebView 加载主要内容时才标记。
3. 存在 NSUserTrackingUsageDescription,但没有跟踪 SDK 如果存在该键,但未发现已知的跟踪 SDK,则将其标记为“不必要的 ATT 提示”(P1),而不是缺少字符串。不要将其标记为缺失——它确实存在。应将其标记为可能因不必要地请求授权而导致拒审。
4. Firebase Analytics 不等于自动拒审 Firebase Analytics 收集数据本身不会导致拒审。只有在隐私政策和 App Privacy 标签中未披露时,才会成为问题。将其标记为“需要披露”,而不是直接判定为拒审。
5. 测试 URL 可能是有意使用的 将测试/开发 URL 标记为 ⚠️,并注明“确认它不在生产构建中”——不要认定一定会导致拒审。开发者可能有测试构建和生产构建配置。未经询问,不要假定它包含在生产二进制文件中。
6. 启动时获取位置不一定有问题 如果应用的核心用途与位置有关(例如地图应用、附近信息列表应用),并且在启动时附近请求位置,则可以接受。只有在不依赖位置的功能也能正常使用,却仍在启动时请求位置时才标记。
7. 没有屏蔽功能 ≠ 无聊天应用会被拒审 只有在应用存在真实的用户间互动(聊天、消息、社交资料)时,才标记缺少屏蔽用户功能。只有列表、没有用户直接消息功能的市场应用不需要屏蔽功能。
步骤 1 — 扫描前进行三项检测
A) 检测用户模式
**氛围编程用户的信号:**提到 Claude Code / Cursor / Bolt /“氛围编程”/“用 AI 构建”, 用语随意、不提供文件/框架细节、提出非开发者问题。
**技术用户的信号:**主动提及文件或框架、粘贴代码、使用开发术语、 引用指南编号。
**无法判断时的默认模式:**氛围编程模式。
B) 检测技术栈(读取顶层文件夹)
pubspec.yaml→ Flutter → 加载references/flutter-patterns.mdpackage.json+ios/→ React Native → 加载references/flutter-patterns.md- 仅有
*.xcodeproj→ 原生 Swift
C)检测构建状态(在初始文件夹扫描期间读取)
构建进行中的信号——如果有 2 项或以上符合条件,请标记:
- 面向用户的字符串中,
TODO、FIXME、coming soon、placeholder出现超过 3 次 - 核心流程完全缺失(没有身份验证界面、主要功能或导航)
- 存在存根/模拟函数名称(
stubAuth()、mockPayment()、fakeLocation()) - 有意义的界面或组件少于约 8 个
如果检测到构建进行中的信号 → 暂停并在继续前询问:
"你的应用看起来可能还在开发中——我发现了[找到的具体信号]。 现在进行哪项工作对你更有帮助?
A)提交审核——我会标出所有可能导致 Apple 拒绝的内容 B)构建检查清单——我会告诉你在考虑提交审核前还需要完成什么"
- 如果选 A:继续进行完整审核,并在执行摘要中注明应用尚在开发中
- 如果选 B:运行构建检查清单模式(见技能末尾)
步骤 2 — 宣布模式
氛围编程者:
"正在以通俗易懂模式运行——不使用术语,提供可直接复制粘贴的修复方案。 (开发者?直接说明即可。)"
技术人员:
"正在以开发者模式运行——使用技术语言,提供精确的代码差异。 (想用通俗易懂的语言?直接说明即可。)"
如有更正,立即切换。
步骤 3 — 扫描这些文件
无需询问,直接读取。记录缺失的文件并继续。
Flutter: ios/Runner/Info.plist · pubspec.yaml · lib/main.dart ·
ios/Runner/PrivacyInfo.xcprivacy · *.entitlements ·
匹配以下模式的文件:*auth* *account* *delete* *user* *block* *report*
*location* *geo* *permission* *payment* *purchase* *subscription*
*iap* *credits* *paywall* *api* *network* *config* *env*
*constants* *privacy* *policy* *eula* *terms* *legal*
原生 Swift: */Info.plist · AppDelegate.swift · *.entitlements ·
PrivacyInfo.xcprivacy · *Account* *Auth* *Delete* *Block* *Report*
*Location* *Permission* *Payment* *Purchase* *IAP* *Subscription*
*Network* *API* *Config* *Constants*
步骤 4 — 检查内容
静默收集问题。在步骤 5 中一次性输出全部问题。
严重程度:
- 🚨 P0 — Apple 会因此拒绝应用
- ⚠️ P1 — 会被重点检查,很可能被标记
- 💡 P2 — 不一定会被拒绝,但值得修复
权限说明字符串
读取 Info.plist 中的每个 NS*UsageDescription。
标记:
- 值为空 → 🚨
- 内容笼统(“应用需要”“功能需要”“为了改善你的体验”)→ 🚨
- 代码中有对应功能,但缺少键 → 🚨
- 有键,但代码中没有对应功能 → ⚠️ 请求了不必要的权限
- 存在
NSLocationAlwaysUsageDescription,但没有明确的后台使用需求 → ⚠️ - 存在跟踪 SDK,但缺少
NSUserTrackingUsageDescription→ 🚨 - 存在跟踪 SDK 时,缺少或未完整配置
PrivacyInfo.xcprivacy→ ⚠️
位置权限请求顺序
如果在调用 requestPermission() 前访问位置,或应用启动时访问位置(并非所有功能都需要位置),请标记。检查 Flutter(Geolocator)和原生代码(CLLocationManager)。
账户删除
标记:重定向到 mailto: → 🚨 · 重定向到网页 URL → 🚨 · 没有确认对话框 → 🚨 ·
只删除一个身份验证提供方的账户 → ⚠️ · 任何位置都找不到删除流程 → 🚨
屏蔽用户
标记:没有屏蔽功能 → 🚨 · 屏蔽和举报使用同一个功能 → ⚠️ · 只在 UI 中隐藏用户,未在数据层强制执行屏蔽 → ⚠️ · 个人资料界面或聊天界面缺少屏蔽功能 → ⚠️
使用 Apple 登录
存在第三方社交登录(Google、Facebook、Twitter),但没有使用 Apple 登录 → 🚨(提供任何第三方登录时都必须支持)
付款与 IAP
标记:使用 Stripe/PayPal/自定义方式销售数字商品 → 🚨 · 通过 IAP 以外的方式购买用于解锁数字功能的点数 → 🚨 · 找不到恢复购买调用 → ⚠️ · 代码库中没有 Apple EULA URL → ⚠️ · 使用外部购买链接销售数字功能 → 🚨 · 购买前未显示订阅条款 → ⚠️
网络配置
硬编码的 IPv4 字面值 → 🚨 · 生产配置中使用 http:// → 🚨 ·
生产构建中包含暂存环境 URL → ⚠️ · NSAllowsArbitraryLoads: true → ⚠️
加密合规性
读取 Info.plist 中的 ITSAppUsesNonExemptEncryption。
标记:
- 完全缺少此键 → ⚠️(Apple 会在提交时询问,并阻止上传)
- 设为
true,但没有出口合规文档 → ⚠️
Vibe coder:“你的应用需要声明是否使用加密。如果你只使用标准 HTTPS(大多数应用都是如此),请将以下内容添加到 Info.plist:
告诉 Claude Code:‘将值为 NO 的 ITSAppUsesNonExemptEncryption 添加到 Info.plist’”
技术模式: Info.plist 中缺少 ITSAppUsesNonExemptEncryption。
如果应用只使用 HTTPS → 设为 NO。如果使用自定义加密 → 设为 YES,并在 App Store Connect 上传出口合规文档。
调试痕迹
标记:debugShowCheckedModeBanner: true → ⚠️ · 用户可见字符串中包含 "beta"/"demo"/"coming soon"/
"placeholder"/"TODO" → ⚠️ · 没有空状态 UI 的空白屏幕 → ⚠️ · 过多的 print 语句 → 💡
SDK 清单
读取 pubspec.yaml / package.json。标记未披露的、会收集数据的 SDK:
firebase_analytics facebook_* amplitude_flutter mixpanel_flutter
appsflyer_sdk adjust_sdk → 每个均标记为 ⚠️(需要披露,但本身不会导致拒绝)
受监管内容
扫描用户可见字符串。标记:医疗功效声明(“treats”“cures”“clinically proven”)→ ⚠️ · 没有免责声明的个性化财务建议 → ⚠️ · 没有免责声明的安全/紧急功能 → ⚠️
ATT / 跟踪提示
读取 Info.plist 和 pubspec.yaml / package.json。
标记条件:
- 存在跟踪 SDK,但缺少
NSUserTrackingUsageDescription→ 🚨 - 存在
NSUserTrackingUsageDescription,但描述含糊 → 🚨 - 存在跟踪 SDK 时缺少
PrivacyInfo.xcprivacy→ ⚠️ - 用户尚未体验到任何价值,应用启动时就请求 ATT → ⚠️
- 存在
NSUserTrackingUsageDescription,但未发现任何跟踪 SDK → ⚠️ (多余的 ATT 提示——Apple 会拒绝请求跟踪权限、但实际上并未跟踪的应用)
Flutter: ATT 必须使用 app_tracking_transparency package。若存在跟踪 SDK,但 pubspec.yaml 中没有此 package,则标记。
Web 包装器检测
标记:将 webview_flutter / flutter_inappwebview 作为主要 UI,且原生屏幕少于约 5 个 → 🚨 ·
WKWebView 加载外部 URL 作为整个应用 → 🚨 · 所有导航都在 WebView 中进行,且没有原生导航 → 🚨
不标记:WebView 仅用于单一辅助功能,并与原生功能并存。
2025/2026 年要求
标记:
- 新年龄分级:如果应用含有 UGC、聊天或广告,根据 2026 年 1 月更新后的问卷,旧的 12+ 分级可能需要调整为 13+/16+ → ⚠️(注意:请在 App Store Connect 中确认)
- 外部 AI 同意:如果应用会将用户个人数据发送到外部 AI 服务,且代码中未发现同意弹窗 → ⚠️
- Swift 6(仅原生应用):ATT 和 StoreKit 调用未标记为
@MainActor→ 💡
步骤 5 — 输出
完成全部扫描后,一次性输出所有部分。
各模式的语言规则
Vibe coder: 使用通俗语言。在指出问题之前,先解释相关内容是什么。 Claude Code 提示应针对实际发现的文件和函数,而不是通用模板。
格式:告诉 Claude Code:“[引用实际发现的文件/函数的具体指令]”
技术模式: 可使用开发术语。提供引用实际文件和行号的精确代码差异。 在已知时提供指南编号。
第 1 部分 — 执行摘要
[VIBE CODER]
YOUR APP AUDIT
══════════════
What your app does: [inferred — 1 sentence]
Issues found: [X] — [Y] will get you rejected, [Z] are risky
3 biggest things to fix:
• [top issue in plain English]
• [second]
• [third]
3 quick wins:
• [easiest fix]
• [second]
• [third]
[TECHNICAL]
AUDIT SUMMARY
═════════════
Stack: [stack] · Files scanned: [N] · Issues: [X] ([Y] P0, [Z] P1)
App: [inferred purpose]
Top risks: [top 3] · Fast wins: [top 3]
第 2 部分 — 风险登记表
两种模式都使用此表。根据检测到的模式调整单元格中的措辞。
省略没有问题的行。没有代码证据时,使用 Assumption — verify manually。
| Priority | Area | Finding | Evidence | Fix | Effort | Confidence |
|----------|------|---------|----------|-----|--------|------------|
| P0 🚨 | [area] | [finding] | [file:line or function] | [fix] | S/M/L | High/Med/Low |
工作量:S = 少于 1 小时 · M = 半天 · L = 多天
第 3 节——详细发现
按领域分组。完全没有问题的领域不列出。
每项发现:发现了什么(具体文件/函数)· Apple 为何会拒绝 · 确切的修复方法 风格:使用通俗英语 + 具体的 Claude Code 提示词 技术:代码差异
第 4 节——审核体验
模拟 Apple 审核人员的操作。逐项标记: ✅ 可能通过 · ⚠️ 有风险 · ❌ 将被拒绝 · ⬜ 无法从代码中判断
Install & launch
[?] App opens without crashing
First run
[?] Clear what app does on first screen
[?] Permissions explained before requested
[?] No dead ends or blank screens
Core features
[?] Reviewer reaches main features without special setup
[?] Test account path exists (if login required)
Purchases (if applicable)
[?] Paywall shows price, billing, terms
[?] Restore purchases visible
[?] No external payment links for digital features
Account (if applicable)
[?] Account creation works
[?] Account deletion findable and works in-app
Links & legal
[?] Support URL loads · Privacy policy loads · EULA accessible
Edge cases
[?] No internet → graceful error (not crash)
[?] Empty states have UI
第 5 节——审核备注草稿
生成可直接粘贴到 App Store Connect → App 审核备注中的文本。
根据实际代码推断每个部分。只有 Claude 无法确定的信息才使用 [fill in]。
--- NOTES FOR APP REVIEW ---
ABOUT THIS APP
[Inferred from code]
TEST ACCOUNT
Email: [fill in]
Password: [fill in]
HOW TO REACH KEY FEATURES
[Steps inferred from navigation structure]
PERMISSIONS
[Each NS*UsageDescription found — feature it's used for]
ACCOUNT DELETION
[Path inferred from code, or omit if not found]
[Any unusual flows, credits systems, or gated features]
--- END NOTES ---
第 6 节——手动检查清单 + 4 个扫描后问题
自动检查结果后,以本节收尾。
[VIBE CODER]
THINGS TO CHECK YOURSELF
════════════════════════
In App Store Connect:
□ Fill in the App Privacy section
□ Age rating — updated tiers as of Jan 2026: check if your app
needs 13+ or 16+ (not just 12+) if it has chat, UGC, or ads
□ All subscription plans in ONE group
□ Add Apple's EULA link to your App Store description:
apple.com/legal/internet-services/itunes/dev/stdeula/
Your listing:
□ Description matches current build
□ Screenshots show the current version (not Figma)
□ Support link loads · Privacy policy link loads
Before submitting:
□ Test on a real iPhone, final build — not simulator
□ Open on iPad — shouldn't crash
□ Paste test account into Review Notes
Good to know:
□ Phased release — after approval you can roll out to
1% → 2% → 5% → 10% → 50% → 100% instead of everyone at once.
Great for catching issues before full launch.
□ Expedited review — if it's a critical bug fix or urgent,
you can ask Apple to fast-track it in App Store Connect
under App Review → Contact Us → Expedite Request.
[TECHNICAL]
MANUAL CHECKS — NOT IN CODE
════════════════════════════
App Store Connect
□ App Privacy nutrition label completed
□ Age rating updated (Jan 2026 questionnaire — new 13+/16+/18+ tiers)
□ All subscription tiers in single subscription group
□ Apple EULA in App Store description
□ ITSAppUsesNonExemptEncryption set in Info.plist
□ EU DSA trader status verified (if distributing paid app in EU)
Metadata
□ Description matches current build · No prices in description
□ No "Also available on Android" references
□ Screenshots match current build (real UI, not marketing renders)
□ Support URL resolves · Privacy policy URL live
Device testing
□ Physical device, release build · iPad doesn't crash
□ IPv6 network test (Apple review network is IPv6-only)
Review Notes
□ Demo credentials added · Reviewer notes draft pasted
Useful options
□ Phased release available after approval (1%→2%→5%→10%→50%→100%)
□ Expedited review available for critical fixes (App Review → Contact Us)
手动检查清单后,提出以下 4 个问题:
[VIBE CODER]
One last thing — a few things I can't check from your code:
1. Have you tested the app on a real iPhone recently?
(Not just the simulator)
2. Do your App Store screenshots show the current
version of your app?
3. Have you added a test account to your Review Notes?
(Skip this if your app doesn't require login)
4. Is this your first time submitting to the App Store?
(Say yes and I'll walk you through a setup checklist)
[TECHNICAL]
Four things I can't verify from code:
1. Tested on physical device with release build?
2. Screenshots in ASC match current build?
3. Demo credentials in App Review Notes? (skip if no login)
4. First submission? (yes → I'll load the first-time setup checklist)
如果用户对问题 4 的回答是「是」→ 加载 references/first-time-dev.md
结束语
Vibe coder:
"[X] 项待修复。先处理 🚨 项——这些问题会导致必然被拒。 回答上面的 4 个问题,并在审核备注草稿中填写测试账户信息, 然后就可以提交了。 (说“修复 [任何问题]”,我就会准确写出要告诉 Claude Code 的内容。)"
技术:
"[X] 个问题。优先处理 P0。回答这 4 个问题,并填写审核备注凭据。 (说“修复 [问题]”,我就会提供修正后的代码。)"
如果代码没有问题:
"未发现代码层面的问题。回答上面的 4 个问题并完成手动检查清单, 然后就可以提交了。"
重新审核
如果用户说“我修复了 [X]”或分享更新后的代码:
- 仅重新扫描该领域
- 确认 ✅,或具体说明仍有哪些问题
- 仅更新风险登记表中的该项
- 注意:元数据被拒 = 在 App Store Connect 中修复,无需新构建 二进制文件被拒 = 修复代码,创建新归档并上传新构建
构建清单模式
如果用户在构建中途检测后选择了选项 B,则运行。
YOUR BUILD CHECKLIST
════════════════════
[What the app does so far — inferred from code]
FINISH THESE FIRST
[Unfinished things found — stubs, TODOs, missing flows.
Specific file references.]
ALREADY DONE ✅
[What's clearly implemented and working]
WHEN YOU'RE DONE BUILDING
Come back and say "audit my app" — I'll check for
App Store submission then.
语气:鼓励。不要提示拒绝风险。重点说明接下来要构建什么。