关于 axiom-app-store-diag
axiom-app-store-diag 面向处理 App Store 审核驳回的开发者,按驳回信息和指南编号匹配诊断方案,涵盖元数据、隐私、技术等问题。
主要功能
- 01识别驳回类型
- 02按指南编号匹配诊断模式
- 03区分元数据修复与重新构建
- 04提供隐私与技术问题修复步骤
- 05说明何时向审核人员询问
适用场景
- 01诊断注明指南编号的驳回
- 02无需新构建即可修正 App Store Connect 元数据
- 03调查隐私或二进制包驳回
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-app-store-diag安装后在 Claude Code 中输入/axiom-app-store-diag确认已加载。
详细介绍
App Store 拒审诊断
概述
系统化诊断并修复 App Store 拒审问题。涵盖 9 种诊断模式,涉及最常见的拒审类别,包括技术、元数据、隐私、业务、主观判断和安全违规。
核心原则 大多数 App Store 拒审都属于常见类别。仔细阅读拒审消息并对应到正确的指南,可避免头号错误:修错问题,结果因同一原因再次被拒。
许多开发者会在拒审循环中浪费 1-2 周,因为他们只是浏览拒审消息、猜测原因,然后“修复”并非问题所在的内容。本技能提供从拒审消息到针对性修复的系统化诊断方法。
危险信号 — 疑似提交问题
如果你看到以下任意情况,请怀疑是提交问题并使用本技能:
-
拒审消息引用了具体的指南编号
-
“Binary Rejected”,但未明确指出指南(技术门槛未通过)
-
同一个 App 因不同原因被拒多次
-
“Metadata Rejected”(无需更改代码)
-
拒审提到“隐私”或“数据收集”
-
拒审提到“登录”或“身份验证”
-
审核员要求提供演示账号或更多信息
-
❌ 禁止“审核员错了,我们直接重新提交吧”
- 重新阅读拒审消息。App Review 在 95% 的情况下是正确的。
- 不做更改就重新提交,每轮会浪费 3-7 天。
- 如果你确实有异议,请使用申诉流程(模式 7)。
必须首先执行的步骤
在更改任何代码之前,务必执行以下操作:
- 阅读完整的拒审消息 — 不要浏览了事。复制原文,记下其中引用的每个指南编号。
- 确定拒审类型:
- “App Rejected” → 违反指南,需要修复代码/内容
- “Metadata Rejected” → ASC 元数据问题,无需构建
- “Binary Rejected” → 技术门槛问题(SDK、清单、加密)
- “Removed from Sale” → 审核通过后的强制处理
- 查看具体指南 — 在 app-store-ref 中查找准确的编号
- 截取拒审消息 — 保存截图,供团队沟通和申诉时参考
- 查看 ASC 中的 App Review 消息 — 有时他们只是索取信息,并非拒审
这意味着什么
| 拒审类型 | 发生了什么 | 下一步 |
|---|---|---|
| “App Rejected” + 指南 2.1 | App 崩溃或包含占位内容 | 模式 1 |
| “Metadata Rejected” | 截图或描述有误 | 模式 2 |
| “App Rejected” + 指南 5.1 | 隐私政策或清单存在遗漏 | 模式 3 |
| “App Rejected” + 指南 4.8 | 缺少“通过 Apple 登录” | 模式 4 |
| “App Rejected” + 指南 3.x | 业务/变现违规 | 模式 5 |
| “Binary Rejected” / 无指南编号 | SDK、签名或加密问题 | 模式 6 |
| 审核员似乎有误 | 确实存在误解 | 模式 7 |
| 引用指南 1.x | 安全/内容问题 | 模式 9 |
| 引用指南 4.1-4.3 | 设计/原创性问题 | 模式 8 |
必须进行的判断
更改任何代码之前,先确定以下一种情况:
- 如果是“App Rejected”且带有指南编号 → 对应到具体模式(1-5)
- 如果是“Metadata Rejected” → 在 ASC 中修复,无需构建(模式 2)
- 如果是“Binary Rejected” → 技术门槛未通过(模式 6)
- 如果引用了多条指南 → 修复所有指出的问题,而不只是第一条。二进制和元数据可能同时被拒;二进制问题需要重新构建,元数据问题可在 ASC 中修复。重新提交前,必须同时修复两者。
- 如果审核员索取信息 → 先在 ASC 中回复,再更改代码
如果拒审原因不明确或前后矛盾
- 停止。暂时不要开始修复代码
- 在 ASC 中回复 App Review,请求澄清
- 附上展示功能正常运行的截图或视频
- 等待回复后再进行更改
决策树
App Store rejection?
│
├─ What does the rejection say?
│ │
│ ├─ Cites Guideline 2.1?
│ │ ├─ App crashed during review? → Pattern 1 (check crash logs)
│ │ ├─ Placeholder content found? → Pattern 1 (search project)
│ │ ├─ Broken links? → Pattern 1 (verify URLs)
│ │ └─ Missing demo credentials? → Pattern 1 (provide in review notes)
│ │
│ ├─ Cites Guideline 2.3?
│ │ ├─ Screenshots don't match app? → Pattern 2 (retake screenshots)
│ │ ├─ Description promises missing features? → Pattern 2 (update text)
│ │ └─ Keywords contain trademarks? → Pattern 2 (remove keywords)
│ │
│ ├─ Cites Guideline 5.1?
│ │ ├─ Privacy policy missing/inaccessible? → Pattern 3 (add/fix policy)
│ │ ├─ Purpose strings missing? → Pattern 3 (add to Info.plist)
│ │ ├─ Privacy manifest incomplete? → Pattern 3 (update PrivacyInfo)
│ │ └─ Tracking without ATT? → Pattern 3 (implement ATT)
│ │
│ ├─ Cites Guideline 4.8?
│ │ ├─ Third-party login without SIWA? → Pattern 4 (add SIWA)
│ │ ├─ SIWA button hidden or broken? → Pattern 4 (fix prominence)
│ │ └─ Exception applies? → Pattern 4 (verify exemption)
│ │
│ ├─ Cites Guideline 3.x?
│ │ ├─ Digital content without IAP? → Pattern 5 (implement StoreKit)
│ │ ├─ Subscription issues? → Pattern 5 (fix terms/value)
│ │ └─ Loot box odds not disclosed? → Pattern 5 (add disclosure)
│ │
│ ├─ "Binary Rejected" / no guideline?
│ │ ├─ Wrong SDK version? → Pattern 6 (update Xcode)
│ │ ├─ Privacy manifest missing? → Pattern 6 (add PrivacyInfo)
│ │ ├─ Encryption not declared? → Pattern 6 (add ITSAppUsesNonExemptEncryption)
│ │ └─ Invalid signing? → Pattern 6 (regenerate provisioning)
│ │
│ ├─ "I believe the reviewer is wrong"?
│ │ └─ → Pattern 7 (Appeal Process)
│ │
│ ├─ Cites Guideline 1.x?
│ │ └─ Safety/content issue → Pattern 9
│ │
│ └─ Cites Guideline 4.1-4.3?
│ └─ Design/originality issue → Pattern 8
模式选择规则(强制)
开始处理某个模式前:
- 复制准确的拒绝文本——逐字复制,包括指南编号
- 将指南编号与模式对应——不要猜测,直接匹配
- 如果引用了多条指南——重新提交前修复所有问题
- 如果没有指南编号——很可能是二元拒绝,从模式 6 开始
- 如果不确定——先回复审核人员,请其澄清
一次应用一种模式
- 根据拒绝消息确定正确的模式
- 完成该模式要求的全部修复
- 如果引用了多条指南,重新提交前逐一修复
- 如果引用了多个问题,切勿只修复其中一个就重新提交
禁止事项
- 不做任何更改就重新提交,寄希望于换一位审核人员
- 粗略浏览拒绝内容后猜测修复方法
- 引用了多条指南时,只修复第一条
- 在 App Review 消息中情绪化地争辩
- 为规避指南 5.1 而禁用隐私功能
诊断模式
模式 1:指南 2.1——App 完整性
耗时 每个拒绝周期 3-7 天
症状
- 拒绝理由引用“App 完整性”
- 审核期间发生崩溃
- 发现占位内容
- 链接失效(支持 URL、隐私政策、App 内链接)
- 需要登录的 App 缺少演示凭据
常见原因
- App 在审核人员的设备上崩溃(操作系统版本不同、设备类别不同)
- 任意屏幕上出现占位文本或图片
- 链接失效(支持 URL、隐私政策、App 内链接)
- 需要登录的 App 缺少演示凭据
- 审核期间后端服务宕机
诊断
# 1. Check crash logs in App Store Connect
# Xcode Organizer > Crashes > Filter by version
# 2. Search for placeholder strings
grep -r "Lorem\|TODO\|FIXME\|placeholder\|sample\|test data" \
--include="*.swift" --include="*.storyboard" --include="*.xib" .
# 3. Verify all URLs resolve
curl -sI "https://your-support-url.com" | head -1
curl -sI "https://your-privacy-policy-url.com" | head -1
# 4. Test on latest shipping iOS
# Check ASC for specific iOS version reviewer used (noted in rejection)
修复
// ❌ WRONG — Demo credentials that expire
// Review Notes: "Login: [email protected] / password123"
// (If this account expires or gets locked, instant rejection)
// ✅ CORRECT — Permanent demo credentials
// Review Notes:
// "Demo Account: [email protected] / ReviewDemo2024!
// This account has pre-populated sample data.
// Account will not expire during review period."
// ❌ WRONG — Placeholder still in code
Text("Lorem ipsum dolor sit amet")
// ✅ CORRECT — Real content in every screen
Text("Welcome to YourApp. Get started by creating your first project.")
验证
- 先提交到 TestFlight,在多台设备上测试每个屏幕
- 确认所有 URL 均可正常加载(包括从 App 内打开的隐私政策)
- 确保演示凭据有效且不会过期
- 在拒绝消息中提到的具体 iOS 版本上进行测试(查看拒绝消息,或前往 ASC Activity → Build → review device info)
- 在审核期间监控后端运行时间(审核期间不要部署)
- 检查 ASC 崩溃日志(Xcode Organizer → Crashes),确认审核人员使用的具体设备和操作系统版本
模式 2:指南 2.3——元数据问题
耗时 1-3 天(修复元数据,无需新构建)
症状
- “元数据被拒绝”——无需更改代码
- 截图与当前 App 界面不符
- 描述承诺了 App 中不存在的功能
- 关键词包含商标名称或竞争对手名称
常见原因
- 截图展示了旧界面或已不存在的功能
- 描述承诺了尚未实现的功能
- 关键词包含商标术语或竞争对手名称
- App 名称暗示了不存在的功能
- 所选类别与 App 的主要功能不符
诊断
将每张截图与当前 App 界面进行比较。逐字阅读描述——其中的每一项描述是否都能在 App 中找到对应功能?对照 Apple 的商标列表检查关键词。
Checklist:
☐ Every screenshot matches current build
☐ Every feature mentioned in description exists and works
☐ No trademarked terms in keywords (e.g., "Instagram", "Uber")
☐ App icon appropriate for all audiences
☐ Age rating matches actual content
☐ Category selection accurate
☐ "What's New" text matches actual changes
修复
直接在 App Store Connect 中更新元数据。仅因元数据问题被拒绝,无需新构建。
✅ Take fresh screenshots FROM THE SUBMITTED BUILD (not dev build)
✅ Remove any features from description that aren't fully functional
✅ Replace trademarked keywords with generic equivalents
("photo sharing" not "Instagram-like")
✅ Ensure "What's New" describes changes in this specific version
验证
- 使用实际提交的构建版本截图
- 请团队以外的人阅读描述,并核实每一项描述
- 检查关键词中是否包含商标术语
模式 3:指南 5.1——隐私违规
耗时 3-10 天(代码 + 清单 + 政策更改)
症状
- 拒绝理由涉及隐私政策、数据收集、用途说明或跟踪
- 隐私清单缺少必需的原因 API 声明
- 第三方 SDK 收集了未披露的数据
常见原因
- 缺少隐私政策,或无法在 App 内访问
- 隐私政策与实际数据收集情况不符
- 权限请求缺少用途说明
- 隐私清单(PrivacyInfo.xcprivacy)缺少必需的原因 API 声明
- 第三方 SDK 收集的数据未在隐私营养标签中披露
- 未经 ATT(App Tracking Transparency)同意便跟踪用户
诊断
// 1. Check: Is privacy policy URL in ASC AND accessible from within the app?
// Both are required. In-app access is commonly missed.
// 2. Check purpose strings
// ❌ WRONG — Generic purpose string
"NSCameraUsageDescription" = "Camera access needed"
// ✅ CORRECT — Specific purpose string explaining why
"NSCameraUsageDescription" = "Take photos for your profile picture and upload to your account"
// 3. Generate privacy report
// Xcode: Product → Archive → Generate Privacy Report
// This shows aggregate data from all frameworks and your code
// 4. Check privacy manifest
// Verify PrivacyInfo.xcprivacy exists in your app target
// AND in every framework target that uses required reason APIs
修复
用途说明(Info.plist)
<key>NSCameraUsageDescription</key>
<string>Take photos for your profile picture and upload to your account</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Show nearby restaurants on the map and calculate delivery distance</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Select photos from your library to attach to messages</string>
隐私清单(PrivacyInfo.xcprivacy)
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
隐私政策要求
Your privacy policy MUST specifically list:
☐ What data is collected (every type)
☐ How data is collected (automatically, user-provided)
☐ All uses of collected data
☐ Third-party sharing (who, why)
☐ Data retention period
☐ How users can request deletion
☐ Contact information for privacy inquiries
App Tracking Transparency
// Required if app tracks users across other companies' apps/websites
import AppTrackingTransparency
func requestTrackingPermission() {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Enable tracking (analytics, ad attribution)
break
case .denied, .restricted, .notDetermined:
// Disable ALL tracking
// Remove IDFA access, disable third-party analytics that track
break
@unknown default:
break
}
}
}
验证
- 生成隐私报告(Product > Archive > Generate Privacy Report),并确认所有 API 均已声明
- 在 App 内测试隐私政策链接(不能只在浏览器中测试)
- 确认每个权限请求都有具体、真实的用途说明
- 审核所有第三方 SDK,检查是否存在未披露的数据收集
- 测试 ATT 流程:拒绝跟踪,并确认 App 在不启用跟踪的情况下仍能正常运行
模式 4:指南 4.8 — 缺少 Sign in with Apple
耗时 3-7 天(实现 + 重新提交)
症状
- 因违反指南 4.8 而被拒
- App 提供第三方登录,但没有 Sign in with Apple(SIWA)
常见原因
- App 提供 Google/Facebook/Twitter 登录,但没有 SIWA
- SIWA 按钮存在但无法使用
- 未以同等显著程度提供 SIWA(隐藏或作为次要选项)
- SIWA 流程未处理凭证撤销
诊断
规则很简单:如果你的 App 使用任何第三方或社交登录服务,就必须提供 Sign in with Apple 作为同等选项。
例外情况(无需提供 SIWA):
- 公司内部或仅供员工使用的 App
- 使用现有机构身份验证的教育或企业 App
- 需要政府身份证件的政府、税务或银行 App
- 作为特定第三方服务客户端的 App(例如邮件客户端)
修复
import AuthenticationServices
// ✅ CORRECT — SIWA at same prominence as other login options
struct LoginView: View {
var body: some View {
VStack(spacing: 16) {
// Sign in with Apple — MUST be at same visual level
SignInWithAppleButton(.signIn) { request in
request.requestedScopes = [.fullName, .email]
} onCompletion: { result in
switch result {
case .success(let authorization):
handleAuthorization(authorization)
case .failure(let error):
handleError(error)
}
}
.signInWithAppleButtonStyle(.black)
.frame(height: 50)
// Other login options at same size/prominence
GoogleSignInButton()
.frame(height: 50)
}
}
func handleAuthorization(_ authorization: ASAuthorization) {
guard let credential = authorization.credential
as? ASAuthorizationAppleIDCredential else { return }
let userIdentifier = credential.user
let fullName = credential.fullName
let email = credential.email
// Note: fullName and email only provided on FIRST sign-in
// Store them immediately — they won't be provided again
// Send to your backend for account creation/login
}
}
// ✅ Handle credential revocation (required for account deletion support)
func checkCredentialState() {
let provider = ASAuthorizationAppleIDProvider()
provider.getCredentialState(forUserID: storedUserIdentifier) { state, error in
switch state {
case .authorized:
break // User is still signed in
case .revoked:
// User revoked credentials — sign out immediately
signOut()
case .notFound:
// Credential not found — show sign-in
showLogin()
@unknown default:
break
}
}
}
验证
- SIWA 按钮在视觉上与其他登录按钮同等显著(尺寸相同,位于同一屏幕)
- 完整的 SIWA 流程均可正常使用:登录、创建账户、检查凭证
- 处理凭证撤销:用户可在 Settings > Apple ID > Sign-In & Security 中撤销
- 测试账户删除流程(自 2022 年 6 月起为必需)
模式 5:指南 3.x — 商业/变现
耗时 3-14 天(可能需要更改架构)
症状
- 因违反商业相关指南而被拒
- 未满足 IAP 要求
- 订阅未提供持续价值
- 使用外部支付购买数字内容
常见原因
- 未通过 IAP 解锁数字内容(使用外部支付购买 App 内功能)
- 订阅未提供持续价值(将一次性内容作为订阅出售)
- 未披露战利品箱或随机物品的购买概率
- 订阅流程具有欺骗性(暗黑模式、误导性的免费试用)
- IAP 元数据不完整,或未提交审核
诊断
关键问题:是否有任何数字内容或功能未通过 Apple IAP 解锁?
Digital goods/features → MUST use Apple IAP
Examples: premium features, virtual currency, ad removal, content
packs, subscription access to digital content
Physical goods/services → MAY use external payment
Examples: physical merchandise, ride-sharing, food delivery,
person-to-person services
Certain categories → MAY use external payment (3.1.3 exceptions)
Examples: "reader" apps (Kindle, Netflix, Spotify), one-to-one
real-time services
修复
// ❌ WRONG — Unlocking features via external payment
func unlockPremium(receiptFromServer: String) {
// Bypass Apple IAP → rejection
UserDefaults.standard.set(true, forKey: "isPremium")
}
// ✅ CORRECT — StoreKit 2 for all digital goods
import StoreKit
func purchasePremium() async throws {
let product = try await Product.products(for: ["com.app.premium"]).first!
let result = try await product.purchase()
switch result {
case .success(let verification):
let transaction = try checkVerified(verification)
// Unlock feature
await transaction.finish()
case .pending:
// Payment pending (Ask to Buy, etc.)
break
case .userCancelled:
break
@unknown default:
break
}
}
// ✅ Loot box disclosure (required if random items for purchase)
struct LootBoxView: View {
var body: some View {
VStack {
Text("Mystery Box — $4.99")
Text("Contents are random. Odds:")
.font(.caption)
// MUST disclose odds before purchase
VStack(alignment: .leading) {
Text("Common item: 60%")
Text("Rare item: 30%")
Text("Legendary item: 10%")
}
.font(.caption2)
.foregroundStyle(.secondary)
}
}
}
验证
- 所有数字内容/功能均使用 Apple IAP(StoreKit 2)
- 在提交 App 之前,已在 ASC 中提交并获批 IAP 商品
- 在购买页面显示前,清楚说明订阅条款
- 清楚显示免费试用时长和自动续订价格
- 在任何购买前披露战利品箱概率
- 不提供用于购买数字商品的外部支付链接(适用“阅读器” App 例外情况时除外)
模式 6:二进制文件被拒 — 技术门槛
耗时 1-3 天(修复构建配置)
症状
- 收到“Binary Rejected”,但未指出具体指南
- 处理期间遭到自动拒绝
- 构建卡在“Processing”状态
常见原因
- 使用过时的 SDK 版本构建(必须满足 Apple 的最低要求)
- 缺少隐私清单(PrivacyInfo.xcprivacy)或清单无效
- 未声明加密合规性(ITSAppUsesNonExemptEncryption)
- 签名或配置描述文件无效
- Info.plist 中缺少必需的设备功能
- 应用使用了私有或已弃用的 API
- 应用二进制文件过大,且未使用按需资源
诊断
# 1. Check Xcode and SDK version
xcodebuild -version
# Must be current or previous major Xcode version
# 2. Check processing logs in ASC
# App Store Connect → My Apps → [App] → Activity → Build → Processing Log
# 3. Verify encryption declaration
grep -c "ITSAppUsesNonExemptEncryption" Info.plist
# Must exist and be set to YES or NO
# 4. Check provisioning
security cms -D -i embedded.mobileprovision 2>/dev/null | head -20
# Verify not expired
# 5. Check for private API usage
# Xcode: Product → Archive → Distribute App → Validate App
# This catches most private API issues before submission
修复
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
加密判定流程:
- 你的应用是否仅使用 OS 提供的标准 HTTPS(URLSession、Alamofire)?→ 设置为
false,完成 - 你的应用是否直接调用 OpenSSL、libsodium 或自定义加密功能?→ 设置为
true,上传 BIS 文档 - 你的应用是否实现了专有加密协议?→ 设置为
true,上传 BIS 文档 - 不确定?→ 运行
strings YourApp | grep -i "openssl\|libcrypto\|CCCrypt"进行检查
# Validate before submitting
# Xcode: Product → Archive → Distribute App → Validate App
# Catches ~80% of binary rejection causes
# Clean build if signing issues
rm -rf ~/Library/Developer/Xcode/DerivedData
# Re-download provisioning profiles in Xcode Preferences → Accounts
验证
- 提交前,在 Xcode Organizer 中运行“Validate App”
- 确认 Xcode 版本符合 Apple 当前的要求
- 检查 PrivacyInfo.xcprivacy 是否存在并包含在应用包中
- 确认 ITSAppUsesNonExemptEncryption 键存在
- 确保配置描述文件尚未过期
- 使用发布配置在实体设备上测试应用
模式 7:申诉流程
解决时间 3-14 天
适用情况
- 你确实认为审核人员误解了你的应用
- 你认为应用被套用了错误的指南
- 你的应用符合要求,并且你有证据
不适用情况
- 你不同意 Apple 的规则(Apple 不会为你的应用更改规则)
- 你希望换一位审核人员就能在不做修改的情况下获批
- 你想跳过实现必需功能(例如 SIWA)
第 1 步:先在 App Store Connect 中回复
大多数问题无需正式申诉即可解决。请在 ASC 中回复 App Review 消息,并提供:
- 符合要求的具体证据
- 展示相关功能的屏幕截图或视频
- 明确指出你认为自己符合的指南
第 2 步:如果问题未解决,提交正式申诉
URL:developer.apple.com/contact/app-store/?topic=appeal
申诉内容撰写
✅ GOOD appeal structure:
"Our app complies with Guideline [X.Y] because [specific evidence].
The reviewer noted: '[quote exact rejection text]'
However, our app [specific counter-evidence with details]:
1. [Feature X] works as shown in [attached screenshot/video]
2. [Policy Y] is accessible at [URL] and within the app at [screen]
3. [Requirement Z] is implemented as described in [technical detail]
Attached: [screenshots, screen recording, or documentation]
We respectfully request re-review of this decision."
❌ BAD appeal examples:
"This is unfair. Other apps do the same thing. Please approve."
→ Apple reviews each app independently
"We've been rejected 3 times and are losing money."
→ Financial pressure is not relevant to guideline compliance
"The reviewer didn't understand our app."
→ Vague. Show specifically what they missed.
"We need this approved by Friday for our launch."
→ Deadlines are not App Review's concern
第 3 步:必要时升级处理
如果申诉被拒:
- 请求与 App Review 进行电话沟通(可通过申诉流程申请)
- 最后再联系 Apple Developer Relations
- 考虑应用是否确实需要进行架构调整
验证
- 如果正在申诉,请等待回复后再更改代码
- 每次拒绝只提交一份申诉(多次申诉会拖慢处理流程)
- 提交申诉前,先回复所有信息请求
模式 8:指南 4.2/4.3 — 最低功能要求 / 垃圾应用
模式 8-9 适用于主观性拒绝;解决方法是证明应用的价值或合规性,而不是更改代码。
解决时间 1-4 周(需要修改应用,而不仅仅是元数据)
你会看到的拒绝消息
- 4.2:“你的应用没有足够的内容和功能,不适合上架 App Store”
- 4.3:“你的应用与由你或其他开发者提交的其他应用在内容和功能上重复”
实际含义
- 4.2(最常见的第 3 类拒绝):“你的应用的价值不足以证明它有必要作为原生应用存在”——与网站相比,没有提供足够的额外价值。
- 4.3(最常见的第 2 类拒绝):“你的应用与另一款应用过于相似,或由模板生成。”Apple 正在积极打击模板工厂式垃圾应用。
检测——这真的属于 4.2/4.3 吗?
在认定拒绝理由成立之前,请检查是否存在分类错误:
# Is the app a WKWebView wrapper?
grep -rn "WKWebView\|SFSafariViewController\|UIWebView" --include="*.swift" .
# Does the app use native features at all?
grep -rn "import CoreLocation\|import AVFoundation\|import UserNotifications\|import HealthKit\|import CoreML" --include="*.swift" .
# Is the codebase template-generated? (common template markers)
grep -rn "powered by\|generated by\|template\|starter kit" --include="*.swift" --include="*.plist" .
如果 WKWebView 是主要 UI,且没有导入原生功能,那么拒绝理由很可能成立。
回复决策树
Is the rejection valid? (be honest)
│
├─ YES, app is thin / web wrapper
│ ├─ Can you add meaningful native features? → Add them (see Evidence Checklist)
│ └─ Core value IS the web content? → Consider reader app model or PWA instead
│
├─ PARTIALLY, app has value but reviewer missed it
│ ├─ Did you provide demo credentials? → If not, resubmit with access
│ ├─ Is the value hidden behind onboarding? → Add review notes explaining path to value
│ └─ Does the app need content/data to show value? → Pre-populate sample data for review
│
└─ NO, app is clearly feature-rich
└─ Appeal with detailed functionality walkthrough (Pattern 7)
Include: feature list, screenshots of each major screen, video demo
证据清单——哪些内容能说服审核人员
针对 4.2(最低功能要求)——证明原生价值:
Features that prove native value:
☐ Offline functionality (data available without network)
☐ Push notifications with meaningful triggers
☐ Device API usage (camera, location, sensors, HealthKit)
☐ Custom UI beyond web content (native controls, animations, gestures)
☐ Local data persistence and sync
☐ Widget, Live Activity, or Watch companion
☐ Accessibility features (VoiceOver, Dynamic Type)
☐ System integration (Shortcuts, Share Extension, Spotlight)
Changes that DON'T help:
✗ Adding a splash screen or settings-only screen to a web wrapper
✗ Cosmetic changes (colors/fonts) without functional native features
针对 4.3(垃圾应用 / 重复应用)——证明独特性:
How to differentiate:
☐ Unique UI that doesn't match other apps in your catalog
☐ Different target audience with distinct feature set
☐ Separate branding (icon, name, color scheme)
☐ Features that justify a separate app vs. being a mode in an existing app
☐ Distinct App Store description and screenshots
☐ Different primary use case (not just themed variants)
If you have multiple similar apps:
☐ Consolidate into one app with multiple modes/themes
☐ Remove duplicates before resubmitting
☐ Explain in review notes why apps need to be separate
沟通模板
Resolution Center response (adapt for 4.2 or 4.3):
"Thank you for your feedback. [Choose one]:
For 4.2: We have added native features that provide value beyond our
web presence: [list features with device capabilities used].
For 4.3: Our app is distinct from [similar app] — different target
audience ([X] vs [Y]), unique features ([list]), separate branding.
[Attach: screenshots of each major screen, 30-60s video walkthrough]
Demo credentials: [username] / [password]"
验证
- 亲自测试应用:你会下载它,而不是使用网站吗?
- 与你的其他应用进行比较:你能清楚说明它们为何要分开吗?
- 预先填充演示数据,让审核人员立即看到价值
- 录制一段 30-60 秒的演示视频,展示原生功能的实际效果
模式 9:指南 1.x — 安全:内容 / UGC / 儿童
解决时间 1-3 周(需要审核基础设施或调整内容)
拒绝消息及其含义
- 1.1:“你的应用包含许多用户会认为不妥的内容”——Apple 会严格审核内容,包括可通过你的应用访问的内容。
- 1.2:“你的应用允许显示用户生成内容,但没有提供足够的机制来举报冒犯性内容”——UGC 缺乏充分审核。没有商量余地:只要用户可以发布任何内容,你就需要一套完整的审核系统。
- 1.3:“你的儿童类别应用必须符合 COPPA” / “包含不适用于儿童类别的第三方分析工具”——儿童类别的规定最严格。任何疏漏都会导致拒绝。
检测——属于哪项子指南?
Does the app have UGC?
├─ YES → Likely 1.2 (moderation required)
│ ├─ Comments, posts, or forums? → Need reporting + moderation
│ ├─ Photo/video uploads visible to others? → Need content review
│ ├─ User profiles visible to others? → Need profile reporting
│ └─ Chat or messaging? → Need blocking + reporting + content filtering
│
├─ Is it in the Kids category?
│ └─ YES → Likely 1.3 (strict requirements)
│ ├─ Any third-party SDKs? → Must be certified for kids
│ ├─ Any external links? → Must be gated or removed
│ └─ Any purchases? → Must have parental gate
│
└─ Does it display third-party or app-provided content?
└─ YES → Likely 1.1 (content standards)
├─ Web content via WKWebView? → Must filter or restrict
├─ AI-generated content? → Must moderate outputs
└─ Content from third-party APIs? → Must filter before display
响应决策树
UGC 被拒(1.2):
What moderation exists?
│
├─ No moderation at all
│ └─ Implement complete moderation system (see Implementation Checklist)
│
├─ Reporting exists but insufficient
│ ├─ Missing blocking? → Add user blocking (immediate effect)
│ ├─ No response workflow? → Add 24-hour review commitment
│ └─ No pre-publish review? → Add content queue or ML filtering
│
└─ Moderation exists but not visible to reviewer
└─ Add review notes explaining moderation flow + demo how to trigger it
儿童类别被拒(1.3):
What triggered the rejection?
│
├─ Third-party SDKs
│ └─ Remove ALL analytics/ads SDKs not certified for Kids category
│ Common offenders: Firebase Analytics, Facebook SDK, AdMob
│ Allowed: Apple's own frameworks, COPPA-certified SDKs only
│
├─ External links
│ └─ Remove all links OR gate behind parental verification
│ Includes: "Visit our website", social media links, "More apps"
│
├─ In-app purchases
│ └─ Add parental gate before ANY purchase flow
│ Gate must require adult knowledge (e.g., "spell this word", math problem)
│ Simple "Are you 18?" button is NOT sufficient
│
└─ Data collection
└─ Remove ALL data collection not essential to app function
No device IDs, no location, no contact info, no tracking
实施清单——最低可行的审核机制(1.2)
Required for ANY app with UGC:
☐ Report button on every piece of user content (visible, not buried)
☐ Block user functionality (immediate, no delay)
☐ Visible Terms of Use / Community Guidelines (accessible from within app)
☐ Content review workflow (human review queue or ML pre-screening)
☐ 24-hour response commitment for reported content
☐ Ability to remove content and ban users
☐ In-app link to Terms of Use from content creation screens
儿童类别要求(1.3)
MANDATORY for Kids category:
☐ COPPA compliance (no data collection from children under 13)
☐ No third-party advertising (none, not even "child-safe" networks)
☐ No external links (or gated behind parental verification)
☐ No social features (no chat, no profiles, no friend lists)
☐ Parental gate before any purchase (not a simple age button)
☐ Remove ALL non-COPPA-certified SDKs (Firebase Analytics, Facebook, AdMob, Crashlytics)
☐ No user tracking of any kind
☐ Privacy policy specifically addresses children's data
沟通模板
Resolution Center response (adapt for 1.2 or 1.3):
"Thank you for your feedback. [Choose one]:
For 1.2 (UGC): We have implemented moderation: report button on all
content [location], user blocking, [review workflow], Terms of Use at
[URL]. To test: create a post → [...] menu → Report.
For 1.3 (Kids): Removed [SDKs]. External links [removed/gated].
Added parental gate for purchases. No user data collected.
Privacy policy updated at [URL].
[Attach: screenshots showing moderation/parental gate flow]"
验证
- 端到端测试举报流程:举报内容,并确认它进入审核队列
- 测试屏蔽流程:屏蔽一名用户,并确认其内容立即隐藏
- 对于儿童类别:从测试设备中移除应用后重新安装,确认没有数据残留
- 对于儿童类别:运行
strings YourApp.app/YourApp | grep -i "firebase\|facebook\|google\|admob",检查嵌入的 SDK - 请一位不熟悉应用的人尝试找到举报 / 屏蔽按钮——如果他们在 5 秒内找不到,说明按钮不够醒目
快速参考表
| 拒绝类型 | 可能原因 | 首要检查项 | 模式 | 典型修复时间 |
|---|---|---|---|---|
| 指南 2.1 | 崩溃 / 占位内容 | 在设备上测试,搜索占位内容 | 1 | 1-3 天 |
| 指南 2.3 | 元数据不匹配 | 将截图与应用进行比较 | 2 | 1 天(无需构建) |
| 指南 5.1 | 隐私方面的疏漏 | 检查政策 + 清单 + 用途说明字符串 | 3 | 2-5 天 |
| 指南 4.8 | 缺少 SIWA | 检查是否有第三方登录 | 4 | 3-5 天 |
| 指南 3.x | 付款方式 | 检查 IAP 流程 | 5 | 3-14 天 |
| 二进制文件被拒 | 技术门槛 | 检查 SDK、清单、加密 | 6 | 1-2 天 |
| 指南 1.x | 安全 / 内容 / UGC | 检查 UGC 审核 + 儿童合规性 | 9 | 1-3 周 |
| 指南 4.2/4.3 | 内容单薄的应用 / 垃圾应用 | 审查原生功能 + 应用独特性 | 8 | 1-4 周 |
生产危机场景
背景:应用第三次被拒,每次原因都不同,明天就是发布日期
情况:市场团队承诺了发布日期。应用先因崩溃被拒(已修复),随后因元数据被拒(已修复),现在又因隐私政策“与实际数据收集情况不符”而被拒。
压力信号:
- 产品团队已经发送了包含发布日期的新闻稿
- 如果推迟发布,App Store 评分可能会下降
- 经理在问“为什么没能早点发现?”
- 想要只快速修复指出的隐私问题
为什么会发生这种情况:每一轮审核都会深入一层。第一轮会发现明显问题(崩溃)。第二轮会检查元数据。第三轮会审查隐私合规性。这很正常,并不是“审核人员在故意针对你”。
合理化陷阱(切勿陷入)
-
“只需修改隐私政策措辞,然后重新提交”
- 审核人员表示“与实际数据收集情况不符”
- 这意味着你的应用收集了未披露的数据
- 不审查实际数据收集情况,只修改措辞 = 再次被拒
-
“审核人员不讲道理,我们申诉吧”
- 因 3 个不同且合理的问题被拒 3 次,并不算不讲道理
- 申诉会浪费 3–14 天,而你本可以在 1–3 天内修复并重新提交
-
“我们删掉涉及隐私的功能,尽快上线”
- 删除功能会改变应用,因此需要重新审核所有内容
- 还可能引入新问题(界面损坏、功能缺失)
-
“下次换个审核人员,可能就不会注意到了”
- 审核人员会查看拒绝记录,并检查之前指出的问题
- 重复被拒会升级至高级审核人员处理
必须采取的做法
- 不要慌,也不要在未彻底修复前重新提交。
- 执行完整的提交前检查清单,而不只是检查被指出的问题。
- 审查所有数据收集:每个 SDK、每次分析调用,以及每个发送用户数据的 API 请求。
- 生成隐私报告(Product > Archive > Generate Privacy Report),并与隐私政策交叉核对。
- 修改隐私政策,明确列出实际收集的每种数据类型。
- 确认之前所有被拒问题仍已修复(崩溃、元数据)。
- 如果确实时间紧迫,请访问 developer.apple.com/contact/app-store/?topic=expedite 申请加急审核。
- 向利益相关方说明:“每次审核都会修复更多问题。本次提交将全面解决隐私合规问题。”
时间对比
| 方案 | 获批时间 |
|---|---|
| 快速修复并重新提交 | 还需 7–14 天(很可能再次被拒) |
| 全面审查并彻底修复 | 3–5 天(把握较大) |
| 全面审查并申请加急审核 | 1–3 天(如获批准) |
专业沟通模板
To stakeholders:
"Root cause: Our third-party analytics SDK collects device identifiers
that weren't disclosed in our privacy policy or nutrition labels.
Fix: Updated privacy policy, privacy nutrition labels in ASC, and
PrivacyInfo.xcprivacy to accurately reflect all data collection.
Also audited all SDKs for undisclosed collection.
Timeline: Resubmitting today with expedited review request.
Expected approval: 1-3 business days.
Prevention: Adding privacy audit to our pre-submission checklist
so future submissions include accurate disclosure from the start."
常见错误
1. 浏览拒绝消息
问题 开发者看到“Guideline 5.1”,便以为自己知道问题所在,没有阅读完整说明。
原因 Guideline 5.1 涵盖隐私政策、用途说明字符串、隐私清单、跟踪以及数据收集披露。拒绝消息会明确指出具体未通过的方面。猜错问题会浪费一个完整的审核周期(3–7 天)。
解决方法:复制完整的拒绝文本。标出其中提及的每项具体要求。编写任何代码前,先将每项要求对应到修复方案。
2. 只修复被指出的问题
问题 拒绝原因指出 Guideline 5.1(隐私),开发者修复了隐私问题,却没有检查其他问题。
原因 审核人员每轮都会发现新问题。第一轮发现崩溃问题,第二轮发现元数据问题,第三轮发现隐私问题。如果你只修复隐私问题,第四轮可能会发现 Guideline 4.8(SIWA)问题。
解决方法:每次重新提交前,都检查所有常见拒绝模式(1–6)。主动修复所有问题。一次彻底的提交胜过三次不完整的提交。
3. 未作任何修改便重新提交
问题 “也许换个审核人员就会批准。”
原因 审核人员会查看拒绝记录。重新提交时若未作修改,结果仍会相同,或者案件会升级至高级审核人员处理。每个浪费掉的周期都会耗费 3–7 天。
解决方法:至少按照审核人员的要求进行修改。如果你认为拒绝有误,请先在 ASC 中提供证据并回复。
4. 在 App Review 消息中情绪化争辩
问题 “这不公平!其他应用都这么做!你们是在阻碍我们的业务!”
原因 App Review 是技术合规审核,不是谈判。情绪化争辩不会被理会。提供合规的具体证据才有效。
解决方法:保持客观、具体、专业。引用相关指南。展示截图。提供技术证据。
5. 忽视第三方 SDK 问题
问题:“我们不收集这些数据——肯定是 SDK 收集的。”
为什么会失败:你的应用要对 SDK 的所有行为负责。如果 Facebook SDK 收集设备标识符,你的隐私政策和营养标签就必须披露这一点。
解决方法:审查每个第三方 SDK。生成隐私报告,查看汇总的数据收集情况。更新隐私政策和营养标签,涵盖所有 SDK 行为。
6. 审核期间部署后端变更
问题:应用正在审核时,推送会改变 API 响应的后端更新。
为什么会失败:审核人员可能会在审核期间的任何时候进行测试。如果后端变更导致正在审核的构建版本出错,就会在审核期间崩溃,导致因违反指南 2.1 而被拒。
解决方法:审核期间冻结后端。如果必须进行变更,请确保与已提交的构建版本向后兼容。
7. 有快速审核机会时却不使用
问题:开发者不知道有快速审核,或在紧急情况下没有申请快速审核。
为什么会失败:明明有正当理由可申请 1 天的快速审核,却还要等待 3-7 天的标准审核。
解决方法:遇到以下情况时,请通过 developer.apple.com/contact/app-store/?topic=expedite 申请快速审核:关键错误修复、有时效性的活动或安全补丁。不要滥用此服务——Apple 会记录使用情况,并可能拒绝你今后的申请。
提交前检查清单
每次提交到 App Store 前,请先逐项检查,以避免被拒:
App Completeness (2.1):
☐ Tested on latest shipping iOS version on physical device
☐ Tested on at least 2 device sizes (iPhone SE, iPhone Pro Max)
☐ No placeholder text (search: Lorem, TODO, FIXME, placeholder, sample)
☐ All URLs resolve (support URL, privacy policy, in-app links)
☐ Demo credentials provided if login required (non-expiring)
☐ Backend stable and not deploying during review window
Metadata (2.3):
☐ Screenshots taken from submitted build (not dev build)
☐ Every feature in description exists and works
☐ No trademarked terms in keywords
☐ Age rating matches content
☐ "What's New" text accurate
Privacy (5.1):
☐ Privacy policy accessible in-app AND via URL in ASC
☐ Privacy policy matches actual data collection
☐ Every permission has specific, honest purpose string
☐ PrivacyInfo.xcprivacy exists and lists all required reason APIs
☐ Privacy Report generated and cross-referenced
☐ ATT implemented if any cross-app tracking
☐ Privacy nutrition labels accurate (including third-party SDKs)
Sign in with Apple (4.8):
☐ If third-party login exists, SIWA offered at same prominence
☐ SIWA flow works: sign in, account creation, revocation handling
☐ Account deletion supported (required since June 2022)
Business (3.x):
☐ All digital goods/features use Apple IAP
☐ IAP products approved in ASC before app submission
☐ Subscription terms clear before purchase
☐ Loot box odds disclosed if applicable
Technical (Binary):
☐ Xcode version meets Apple's current requirements
☐ "Validate App" passes in Xcode Organizer
☐ ITSAppUsesNonExemptEncryption key present
☐ Provisioning profile not expired
☐ Tested with release configuration on device
Safety & Content (1.x):
☐ If UGC: report, block, and moderation workflow all functional
☐ If Kids category: no non-COPPA SDKs, no external links, parental gate on purchases
☐ AI-generated or third-party content has moderation/filtering
Design & Originality (4.2/4.3):
☐ App provides native value beyond a website (offline, push, device APIs)
☐ App is distinct from other apps in your catalog
☐ Demo data pre-populated for reviewer if app needs content to show value
交叉引用
- app-store-connect-ref — ASC 崩溃分析、TestFlight 反馈、指标仪表板
- privacy-ux — 隐私清单实现详情和必需的原因 API
- storekit-ref — StoreKit 2 IAP/订阅实现
- accessibility-diag — 无障碍合规(VoiceOver、Dynamic Type、WCAG)
- ios-build — 导致二进制文件被拒的构建和签名问题
资源
WWDC:2025-328
文档:/app-store/review/guidelines、/distribute/app-review、/support/offering-account-deletion-in-your-app、/contact/app-store/?topic=appeal
技能:app-store-connect-ref、privacy-ux、storekit-ref、accessibility-diag