Use when preparing ANY app for App Store submission - enforces pre-flight checklist, rejection prevention, privacy compliance, and metadata completeness to prevent common App Store rejections
Enforces App Store submission compliance with pre-flight checklists to prevent common rejection causes.
npx claudepluginhub charleswiltgen/axiomThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Systematic pre-flight checklist that catches 90% of App Store rejection causes before submission. Core principle: Ship once, ship right. Over 40% of App Store rejections cite Guideline 2.1 (App Completeness) — crashes, placeholders, broken links. Another 30% are metadata and privacy issues. A disciplined pre-flight process eliminates these preventable rejections.
Key insight: Apple rejected nearly 1.93 million submissions in 2024. Most rejections are not policy disagreements — they are checklist failures. A 30-minute pre-flight saves 3-7 days of rejection-fix-resubmit cycles.
✅ Use this skill when:
❌ Do NOT use this skill for:
Real questions developers ask that this skill answers:
The skill provides a complete pre-flight checklist covering build, privacy, metadata, accounts, review info, content, and regional requirements
The skill walks through every requirement from scratch — privacy manifest, metadata fields, screenshots, demo credentials, age rating
The skill provides anti-patterns with specific rejection causes and the decision tree to identify gaps
The skill provides a categorized mandatory checklist with every item that triggers rejection if missing
Yes. Since May 2024, missing privacy manifests cause automatic rejection. The skill explains when and how.
The skill covers metadata completeness requirements and the common gaps that trigger Guideline 2.3 rejections
Time cost: 3-7 days (rejection + fix + resubmit wait)
Symptom: Rejection for Guideline 2.1 — App Completeness. Crashes, broken flows, or missing functionality discovered by App Review.
❌ BAD: Test only in Simulator, submit when build succeeds
"It works in Simulator, ship it"
→ Rejection: App crashes on launch on iPhone 15 Pro (memory limit)
→ 3-7 day delay
✅ GOOD: Test on physical device with latest shipping OS, exercise all user flows
# Build for device
xcodebuild -scheme YourApp \
-destination 'platform=iOS,name=Your iPhone'
# Test critical paths:
# - Launch → main screen loads
# - All tabs/screens accessible
# - Core user flows complete without crash
# - Edge cases: no network, low storage, interruptions
Why it works: Simulator hides real-device constraints — memory limits, cellular networking behavior, hardware-specific APIs, thermal throttling. App Review tests on physical devices.
Time cost: 2-5 days (rejection + policy creation + resubmit)
Symptom: Rejection for Guideline 5.1.1(i) — Data Collection and Storage. Privacy policy missing, inaccessible, or inconsistent with actual data practices.
❌ BAD: No privacy policy URL, or a generic template that doesn't match actual data collection
Privacy Policy URL: (empty)
— or —
Privacy Policy: "We respect your privacy" (generic, no specifics)
✅ GOOD: Privacy policy accessible in two places, specific to your app's data practices
1. App Store Connect → App Information → Privacy Policy URL
2. In-app → Settings/About screen → Privacy Policy link
3. Policy content lists:
- All collected data types
- How each type is used
- Third-party sharing (who and why)
- Data retention period
- How to request deletion
Three-way consistency: Apple compares (a) your app's actual behavior, (b) your privacy policy content, and (c) your Privacy Nutrition Labels in ASC. All three must agree. If any of these three disagree, you get a 5.1.1 rejection. Check each SDK's documentation for its privacy manifest and data collection disclosure — your app's total data collection is your code PLUS all SDK data collection.
Why it works: Guideline 5.1.1(i) requires privacy policy accessible BOTH in ASC metadata AND within the app. The policy must specifically describe your app's data practices, not a generic template.
Time cost: 3-5 days (rejection + content replacement + resubmit)
Symptom: Rejection for Guideline 2.1 — App Completeness. Reviewers find placeholder text, empty screens, or TODO artifacts.
❌ BAD: Ship with development artifacts visible to users
- "Lorem ipsum" text in onboarding
- Empty tab that shows "Coming Soon"
- Button that opens alert "Not implemented yet"
- Default app icon (white grid)
✅ GOOD: Every screen has final content and production assets
Pre-submission content audit:
- [ ] Every screen has real content (no lorem ipsum)
- [ ] All images are final production assets
- [ ] No "Coming Soon" or "Under Construction" screens
- [ ] All buttons perform their intended action
- [ ] Default/empty states have proper messaging
- [ ] App icon is final and meets spec (1024x1024, no alpha)
Why it works: App Review tests every screen and tab, including states you might consider edge cases. They open every menu, tap every button, and switch every tab.
Time cost: 1-3 days (automatic rejection + manifest creation + resubmit)
Symptom: Automatic rejection before human review. Missing PrivacyInfo.xcprivacy or undeclared Required Reason APIs.
❌ BAD: No privacy manifest, or missing Required Reason API declarations
No PrivacyInfo.xcprivacy in project
— or —
Using UserDefaults, file timestamps, disk space APIs
without declaring approved reasons
✅ GOOD: Privacy manifest present with all Required Reason APIs declared
Project must contain:
├── PrivacyInfo.xcprivacy
│ ├── NSPrivacyTracking (true/false)
│ ├── NSPrivacyTrackingDomains (if tracking)
│ ├── NSPrivacyCollectedDataTypes (all types)
│ └── NSPrivacyAccessedAPITypes (all Required Reason APIs)
│
└── Third-party SDK manifests (each SDK includes its own)
Common Required Reason APIs that need declaration:
UserDefaults → Reason CA92.1C617.1E174.135F9.1Why it works: Since May 2024, this is an automated gate. No human reviewer involved — the build processing system rejects submissions missing required privacy declarations.
Time cost: 3-7 days (SIWA implementation + resubmit)
Symptom: Rejection for Guideline 4.8. App offers third-party login (Google, Facebook, email) but no Sign in with Apple option.
❌ BAD: Third-party login without SIWA
// Login screen offers:
// - Sign in with Google
// - Sign in with Facebook
// - Email/password
// ← Missing: Sign in with Apple
✅ GOOD: SIWA offered as equivalent option alongside any third-party login
// Login screen offers:
// - Sign in with Apple ← Required if others exist
// - Sign in with Google
// - Sign in with Facebook
// - Email/password
Exceptions (SIWA not required):
Why it works: Guideline 4.8 requires SIWA as an option whenever ANY third-party or social login is offered. Apple enforces this strictly.
Time cost: 5-10 days (implementation + testing + resubmit)
Symptom: Rejection for Guideline 5.1.1(v). App allows account creation but provides no way to delete the account.
❌ BAD: Account creation without deletion capability
- Sign up button exists
- No "Delete Account" anywhere in app
- "Contact support to delete" (not sufficient)
- "Deactivate account" (not the same as delete)
✅ GOOD: Full account deletion flow accessible in-app
Account deletion requirements:
1. Discoverable in Settings/Profile (not hidden)
2. Clearly labeled "Delete Account" (not "Deactivate")
3. Explains what deletion means (data removed, timeline)
4. Confirms completion to user
5. If Sign in with Apple used → revoke SIWA token
6. If active subscriptions → inform user to cancel first
7. Deletion completes within reasonable timeframe (days, not months)
// Revoking Sign in with Apple token (required)
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
// After user confirms deletion:
// POST to Apple's revoke endpoint with the user's token
// Then delete server-side account data
Why it works: Required since June 2022. Must be actual deletion (not deactivation), must be in-app (not just email/website), and must revoke SIWA tokens if used. Apple tests this flow specifically.
Time cost: 2-4 days (re-answer questionnaire + possible content changes + resubmit)
Symptom: Rejection for Guideline 2.3.6 — Inaccurate metadata. Age rating doesn't reflect actual app content or capabilities.
❌ BAD: Understate content to get lower rating
App has user-generated content (chat, posts)
but age rating questionnaire answered "No UGC"
App has cartoon violence in gameplay
but answered "No violence"
✅ GOOD: Answer age rating questionnaire accurately
Declare honestly:
- User-generated content (chat, forums, social features)
- Violence (even cartoon/fantasy)
- Mature themes
- Profanity / crude humor
- Gambling (simulated or real)
- Horror / fear themes
- Medical / treatment information
- Unrestricted web access (WebView with open URLs)
New age ratings (January 31, 2026): Apple expanded from 4+/9+/12+/17+ to 5 tiers (4+/9+/13+/16+/18+) with new capability declarations for messaging, UGC, advertising, and parental controls. All developers must complete the updated questionnaire or app updates will be blocked.
Why it works: Mismatched ratings violate Guideline 2.3.6. Apple compares your questionnaire answers against observed app behavior. UGC and web access are the most commonly missed declarations.
Time cost: 3-5 days (rejection + credential creation + resubmit wait)
Symptom: Rejection for Guideline 2.1. Reviewer unable to test app because login is required and no test account was provided.
❌ BAD: App requires login, but no demo account in review notes
App Review Information:
Notes: (empty)
Demo Account: (empty)
Demo Password: (empty)
→ Reviewer sees login screen, can't proceed, rejects
✅ GOOD: Working demo credentials with clear instructions
App Review Information:
Demo Account: demo@yourapp.com
Demo Password: AppReview2025!
Notes: "Log in with the demo account above.
The account has sample data pre-loaded.
To test [feature X], navigate to Tab 2 > Settings.
If 2FA is required, use code: 123456"
Requirements:
- Account must not expire during review (1-2 weeks minimum)
- Account must have representative data
- Include any special setup steps
- If hardware required, explain workarounds
- If location-specific, provide test coordinates
Why it works: Reviewers cannot test what they cannot access. They will not create their own account. If your app requires any form of authentication, demo credentials are mandatory. This is one of the most common rejection reasons for apps with login flows.
Is my app ready to submit?
│
├─ Does it crash on a real device?
│ ├─ YES → STOP. Fix crashes first (Guideline 2.1)
│ └─ NO → Continue
│
├─ Privacy manifest (PrivacyInfo.xcprivacy) present?
│ ├─ NO → Add privacy manifest with Required Reason APIs
│ └─ YES → Continue
│
├─ Privacy policy URL set in App Store Connect?
│ ├─ NO → Add privacy policy URL in ASC
│ └─ YES → Is it also accessible in-app?
│ ├─ NO → Add in-app privacy policy link
│ └─ YES → Continue
│
├─ All screenshots final and matching current app?
│ ├─ NO → Update screenshots for all required device sizes
│ └─ YES → Continue
│
├─ Does app create user accounts?
│ ├─ YES → Account deletion implemented and discoverable?
│ │ ├─ NO → Implement account deletion flow
│ │ └─ YES → Continue
│ └─ NO → Continue
│
├─ Does app offer third-party login (Google, Facebook, etc.)?
│ ├─ YES → Sign in with Apple offered?
│ │ ├─ NO → Add SIWA (unless exemption applies)
│ │ └─ YES → Continue
│ └─ NO → Continue
│
├─ Does app have in-app purchases or subscriptions?
│ ├─ YES → IAP items submitted for review in ASC?
│ │ ├─ NO → Submit IAP for review (can be reviewed separately)
│ │ └─ YES → Restore Purchases button implemented?
│ │ ├─ NO → Add Restore Purchases functionality
│ │ └─ YES → Continue
│ └─ NO → Continue
│
├─ Does app use encryption beyond standard HTTPS?
│ ├─ YES → Export compliance documentation uploaded?
│ │ ├─ NO → Add ITSAppUsesNonExemptEncryption to Info.plist
│ │ │ and upload compliance documentation
│ │ └─ YES → Continue
│ └─ NO → Set ITSAppUsesNonExemptEncryption = NO in Info.plist
│
├─ Distributing in EU?
│ ├─ YES → DSA trader status verified in ASC?
│ │ ├─ NO → Complete trader verification in ASC
│ │ └─ YES → Continue
│ └─ NO → Continue
│
├─ Does app require login to function?
│ ├─ YES → Demo credentials in App Review notes?
│ │ ├─ NO → Add working demo account + password + instructions
│ │ └─ YES → Continue
│ └─ NO → Continue
│
├─ Age rating questionnaire completed honestly?
│ ├─ NO → Complete updated questionnaire (new 13+/16+/18+ ratings)
│ └─ YES → Continue
│
├─ Any placeholder content remaining?
│ ├─ YES → Replace all placeholders with final content
│ └─ NO → Continue
│
└─ All checks passed → READY TO SUBMIT
Run this entire checklist before every submission. Check every item, not just the ones you think apply.
ITSAppUsesNonExemptEncryption set in Info.plist (NO if only HTTPS)PrivacyInfo.xcprivacy file present in app targetNS*UsageDescription purpose strings present (Camera, Location, etc.)Setup: PM says the app must be submitted today for a marketing launch next week.
Pressure: Deadline + executive visibility
Rationalization traps:
MANDATORY: Run the full pre-flight checklist. Every item. Missing items cause rejection, which costs 3-7 MORE days — far worse than the 30 minutes the checklist takes.
Skipping the checklist to save 30 minutes costs 3-7 days when it causes rejection.
Communication template: "The pre-flight check found [N] issues that will cause rejection. Fixing them takes [X hours]. Submitting without fixing guarantees rejection, which costs 3-7 days minimum. Let me fix these now — it's the fastest path to being live."
Setup: App rejected 3 times for different issues each time. Developer is frustrated and tempted to cut corners or argue with Apple.
Pressure: Frustration + sunk cost + temptation to appeal instead of fix
Rationalization traps:
MANDATORY: Read the FULL text of every rejection message. Run the complete pre-flight checklist from scratch. Reviewers often find new issues on subsequent reviews because they test deeper each pass — they explore screens they didn't reach before, test flows they skipped, and review with stricter attention.
Each rejection is a signal that the pre-submission process has gaps. Do not fight the feedback — absorb it and close the gaps systematically.
Communication template: "Multiple rejections mean we have systematic gaps, not bad luck. I'm running the complete pre-flight checklist — this takes 30 minutes but prevents the 3-7 day cycle of partial fixes followed by new rejections."
Setup: Simple one-line bug fix. Developer assumes the update will sail through because the app was already approved.
Pressure: Complacency + false confidence from prior approval
Rationalization traps:
MANDATORY: Updates are reviewed against CURRENT guidelines. Requirements change between releases. Privacy manifests became mandatory mid-cycle. Age rating questionnaire was overhauled. SDK minimums increase annually. A bug fix update can be rejected for issues that didn't exist when the previous version was approved.
Run the pre-flight checklist every time. Requirements that didn't exist when your app was last reviewed may now be enforced.
Communication template: "Even for a bug fix, App Review applies current guidelines — not the ones from when we were last approved. The privacy manifest requirement and age rating overhaul both came mid-cycle. Running the 30-minute pre-flight now prevents a surprise rejection."
Screenshots must match current app UI. See app-store-ref Part 1 for required sizes, dimensions, and rules.
Every rejection includes:
1. Read the FULL rejection message (every word)
2. Identify ALL guidelines cited (may be multiple)
3. Fix EVERY cited issue (not just the first one)
4. Run the complete pre-flight checklist
5. In your resubmission notes, explain what you fixed
6. Do NOT argue or explain why you think the rejection is wrong
Appeals are appropriate when:
Appeals are NOT appropriate when:
App Store Connect → Resolution Center → Reply
- Explain clearly why you believe the rejection is incorrect
- Provide specific evidence (screenshots, documentation)
- Remain professional and factual
- Apple's App Review Board will re-review
| Type | What it means | What to do |
|---|---|---|
| Metadata Rejected | Screenshots, description, or ASC fields need fixing | Fix in ASC, resubmit (no new build needed) |
| Binary Rejected | Code/app issue needs fixing | Fix code, create new archive, upload new build |
IAP items require separate review. Missing or broken IAP is a top rejection cause under Guideline 3.1.1.
❌ "Buy Premium" button that does nothing → Guideline 3.1.1
❌ No Restore Purchases option → Guideline 3.1.1
❌ Subscription auto-renews without clear disclosure → Guideline 3.1.2
❌ Free trial duration not shown before purchase → Guideline 3.1.2
❌ External purchase link without entitlement → Guideline 3.1.1
| Guideline | Issue | Prevention |
|---|---|---|
| 2.1 | Crashes, broken features, incomplete | Device testing, content audit |
| 2.3 | Inaccurate metadata, wrong screenshots | Screenshot audit, metadata review |
| 2.3.6 | Incorrect age rating | Honest questionnaire, declare UGC |
| 3.1.1 | IAP issues, missing Restore Purchases | Test all IAP flows, add restore |
| 4.0 | Design: poor UI, non-standard patterns | Follow HIG, test on all sizes |
| 4.8 | Missing Sign in with Apple | Add SIWA with any third-party login |
| 5.1.1(i) | Privacy policy missing/inadequate | Both ASC and in-app, specific content |
| 5.1.1(v) | No account deletion | In-app deletion, not just deactivation |
| 5.1.2 | Missing Required Reason APIs | Complete privacy manifest |
See app-store-ref Part 9 for the ASC upload workflow and build processing details.
Most apps need ITSAppUsesNonExemptEncryption = false. See app-store-ref Part 5 for the full decision tree.
Accessibility Nutrition Labels are becoming required for new submissions. See app-store-ref Part 10 for the full label list and declaration rules. Run axiom-accessibility-diag before declaring.
For developers submitting their first app, these are additional items often missed. If you need to create a privacy policy from scratch, use a privacy policy generator (many free options exist) and customize it to match your app's actual data practices — a generic template will be rejected.
| Mistake | Result | Fix |
|---|---|---|
| Bundle ID mismatch between Xcode and ASC | Upload rejected | Match exactly, including case |
| Distribution cert expired/missing | Archive fails to upload | Create new cert in Developer Portal |
| License agreement not accepted | Upload blocked | Accept in developer.apple.com |
| Tax forms incomplete | Paid app not distributed | Complete in ASC → Agreements, Tax, and Banking |
| Wrong team selected in Xcode | Signing errors | Select correct team in Signing & Capabilities |
Before: Developer submits without checklist → rejected for missing privacy manifest (3 days) → fixes, resubmits → rejected for missing SIWA (5 days) → fixes, resubmits → rejected for placeholder content (3 days) → 11 days lost to preventable issues
After: Developer runs 30-minute pre-flight → catches all three issues → fixes in 4 hours → approved on first submission
Key insight: The checklist takes 30 minutes. Each rejection cycle takes 3-7 days. The math is simple.
WWDC: 2022-10166, 2025-328, 2025-224, 2025-241
Docs: /app-store/review/guidelines, /app-store/submitting, /app-store/app-privacy-details, /support/offering-account-deletion-in-your-app, /documentation/security/complying-with-encryption-export-regulations
Skills: axiom-privacy-ux, axiom-storekit-ref, axiom-accessibility-diag, axiom-testflight-triage, axiom-app-store-connect-ref
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.