mcpField
A
axiom-app-store-diag

axiom-app-store-diag

github.com/charleswiltgen开发1.2k110 次安装今天更新
代码仓库

关于 axiom-app-store-diag

axiom-app-store-diag 面向处理 App Store 审核驳回的开发者,按驳回信息和指南编号匹配诊断方案,涵盖元数据、隐私、技术等问题。

主要功能

  1. 01识别驳回类型
  2. 02按指南编号匹配诊断模式
  3. 03区分元数据修复与重新构建
  4. 04提供隐私与技术问题修复步骤
  5. 05说明何时向审核人员询问

适用场景

  1. 01诊断注明指南编号的驳回
  2. 02无需新构建即可修正 App Store Connect 元数据
  3. 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)。

必须首先执行的步骤

在更改任何代码之前,务必执行以下操作:

  1. 阅读完整的拒审消息 — 不要浏览了事。复制原文,记下其中引用的每个指南编号。
  2. 确定拒审类型:
    • “App Rejected” → 违反指南,需要修复代码/内容
    • “Metadata Rejected” → ASC 元数据问题,无需构建
    • “Binary Rejected” → 技术门槛问题(SDK、清单、加密)
    • “Removed from Sale” → 审核通过后的强制处理
  3. 查看具体指南 — 在 app-store-ref 中查找准确的编号
  4. 截取拒审消息 — 保存截图,供团队沟通和申诉时参考
  5. 查看 ASC 中的 App Review 消息 — 有时他们只是索取信息,并非拒审
这意味着什么
拒审类型发生了什么下一步
“App Rejected” + 指南 2.1App 崩溃或包含占位内容模式 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
必须进行的判断

更改任何代码之前,先确定以下一种情况:

  1. 如果是“App Rejected”且带有指南编号 → 对应到具体模式(1-5)
  2. 如果是“Metadata Rejected” → 在 ASC 中修复,无需构建(模式 2)
  3. 如果是“Binary Rejected” → 技术门槛未通过(模式 6)
  4. 如果引用了多条指南 → 修复所有指出的问题,而不只是第一条。二进制和元数据可能同时被拒;二进制问题需要重新构建,元数据问题可在 ASC 中修复。重新提交前,必须同时修复两者。
  5. 如果审核员索取信息 → 先在 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

模式选择规则(强制)

开始处理某个模式前:

  1. 复制准确的拒绝文本——逐字复制,包括指南编号
  2. 将指南编号与模式对应——不要猜测,直接匹配
  3. 如果引用了多条指南——重新提交前修复所有问题
  4. 如果没有指南编号——很可能是二元拒绝,从模式 6 开始
  5. 如果不确定——先回复审核人员,请其澄清
一次应用一种模式
  • 根据拒绝消息确定正确的模式
  • 完成该模式要求的全部修复
  • 如果引用了多条指南,重新提交前逐一修复
  • 如果引用了多个问题,切勿只修复其中一个就重新提交
禁止事项
  • 不做任何更改就重新提交,寄希望于换一位审核人员
  • 粗略浏览拒绝内容后猜测修复方法
  • 引用了多条指南时,只修复第一条
  • 在 App Review 消息中情绪化地争辩
  • 为规避指南 5.1 而禁用隐私功能

诊断模式

模式 1:指南 2.1——App 完整性

耗时 每个拒绝周期 3-7 天

症状
  • 拒绝理由引用“App 完整性”
  • 审核期间发生崩溃
  • 发现占位内容
  • 链接失效(支持 URL、隐私政策、App 内链接)
  • 需要登录的 App 缺少演示凭据
常见原因
  1. App 在审核人员的设备上崩溃(操作系统版本不同、设备类别不同)
  2. 任意屏幕上出现占位文本或图片
  3. 链接失效(支持 URL、隐私政策、App 内链接)
  4. 需要登录的 App 缺少演示凭据
  5. 审核期间后端服务宕机
诊断
# 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 中不存在的功能
  • 关键词包含商标名称或竞争对手名称
常见原因
  1. 截图展示了旧界面或已不存在的功能
  2. 描述承诺了尚未实现的功能
  3. 关键词包含商标术语或竞争对手名称
  4. App 名称暗示了不存在的功能
  5. 所选类别与 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 收集了未披露的数据
常见原因
  1. 缺少隐私政策,或无法在 App 内访问
  2. 隐私政策与实际数据收集情况不符
  3. 权限请求缺少用途说明
  4. 隐私清单(PrivacyInfo.xcprivacy)缺少必需的原因 API 声明
  5. 第三方 SDK 收集的数据未在隐私营养标签中披露
  6. 未经 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)
常见原因
  1. App 提供 Google/Facebook/Twitter 登录,但没有 SIWA
  2. SIWA 按钮存在但无法使用
  3. 未以同等显著程度提供 SIWA(隐藏或作为次要选项)
  4. 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 要求
  • 订阅未提供持续价值
  • 使用外部支付购买数字内容
常见原因
  1. 未通过 IAP 解锁数字内容(使用外部支付购买 App 内功能)
  2. 订阅未提供持续价值(将一次性内容作为订阅出售)
  3. 未披露战利品箱或随机物品的购买概率
  4. 订阅流程具有欺骗性(暗黑模式、误导性的免费试用)
  5. 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”状态
常见原因
  1. 使用过时的 SDK 版本构建(必须满足 Apple 的最低要求)
  2. 缺少隐私清单(PrivacyInfo.xcprivacy)或清单无效
  3. 未声明加密合规性(ITSAppUsesNonExemptEncryption)
  4. 签名或配置描述文件无效
  5. Info.plist 中缺少必需的设备功能
  6. 应用使用了私有或已弃用的 API
  7. 应用二进制文件过大,且未使用按需资源
诊断
# 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/>

加密判定流程:

  1. 你的应用是否仅使用 OS 提供的标准 HTTPS(URLSession、Alamofire)?→ 设置为 false,完成
  2. 你的应用是否直接调用 OpenSSL、libsodium 或自定义加密功能?→ 设置为 true,上传 BIS 文档
  3. 你的应用是否实现了专有加密协议?→ 设置为 true,上传 BIS 文档
  4. 不确定?→ 运行 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 步:必要时升级处理

如果申诉被拒:

  1. 请求与 App Review 进行电话沟通(可通过申诉流程申请)
  2. 最后再联系 Apple Developer Relations
  3. 考虑应用是否确实需要进行架构调整
验证
  • 如果正在申诉,请等待回复后再更改代码
  • 每次拒绝只提交一份申诉(多次申诉会拖慢处理流程)
  • 提交申诉前,先回复所有信息请求

模式 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崩溃 / 占位内容在设备上测试,搜索占位内容11-3 天
指南 2.3元数据不匹配将截图与应用进行比较21 天(无需构建)
指南 5.1隐私方面的疏漏检查政策 + 清单 + 用途说明字符串32-5 天
指南 4.8缺少 SIWA检查是否有第三方登录43-5 天
指南 3.x付款方式检查 IAP 流程53-14 天
二进制文件被拒技术门槛检查 SDK、清单、加密61-2 天
指南 1.x安全 / 内容 / UGC检查 UGC 审核 + 儿童合规性91-3 周
指南 4.2/4.3内容单薄的应用 / 垃圾应用审查原生功能 + 应用独特性81-4 周

生产危机场景

背景:应用第三次被拒,每次原因都不同,明天就是发布日期

情况:市场团队承诺了发布日期。应用先因崩溃被拒(已修复),随后因元数据被拒(已修复),现在又因隐私政策“与实际数据收集情况不符”而被拒。

压力信号:

  • 产品团队已经发送了包含发布日期的新闻稿
  • 如果推迟发布,App Store 评分可能会下降
  • 经理在问“为什么没能早点发现?”
  • 想要只快速修复指出的隐私问题

为什么会发生这种情况:每一轮审核都会深入一层。第一轮会发现明显问题(崩溃)。第二轮会检查元数据。第三轮会审查隐私合规性。这很正常,并不是“审核人员在故意针对你”。

合理化陷阱(切勿陷入)
  1. “只需修改隐私政策措辞,然后重新提交”

    • 审核人员表示“与实际数据收集情况不符”
    • 这意味着你的应用收集了未披露的数据
    • 不审查实际数据收集情况,只修改措辞 = 再次被拒
  2. “审核人员不讲道理,我们申诉吧”

    • 因 3 个不同且合理的问题被拒 3 次,并不算不讲道理
    • 申诉会浪费 3–14 天,而你本可以在 1–3 天内修复并重新提交
  3. “我们删掉涉及隐私的功能,尽快上线”

    • 删除功能会改变应用,因此需要重新审核所有内容
    • 还可能引入新问题(界面损坏、功能缺失)
  4. “下次换个审核人员,可能就不会注意到了”

    • 审核人员会查看拒绝记录,并检查之前指出的问题
    • 重复被拒会升级至高级审核人员处理
必须采取的做法
  1. 不要慌,也不要在未彻底修复前重新提交。
  2. 执行完整的提交前检查清单,而不只是检查被指出的问题。
  3. 审查所有数据收集:每个 SDK、每次分析调用,以及每个发送用户数据的 API 请求。
  4. 生成隐私报告(Product > Archive > Generate Privacy Report),并与隐私政策交叉核对。
  5. 修改隐私政策,明确列出实际收集的每种数据类型。
  6. 确认之前所有被拒问题仍已修复(崩溃、元数据)。
  7. 如果确实时间紧迫,请访问 developer.apple.com/contact/app-store/?topic=expedite 申请加急审核。
  8. 向利益相关方说明:“每次审核都会修复更多问题。本次提交将全面解决隐私合规问题。”
时间对比
方案获批时间
快速修复并重新提交还需 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

评论

支持 Markdown