🍎 iOS App Store Deployment Checklist
Flutter / React Native / Native iOS — 2026 Edition
Last updated: April 2026 | Reflects Apple's latest SDK requirements (iOS 26 SDK mandatory from April 28, 2026)
Legend
| Tag | Meaning |
|---|---|
🔴 [BLOCKER] | App will be rejected without this |
🟠 [MANDATORY] | Required by policy — may not cause immediate rejection but risks it |
🟡 [RECOMMENDED] | Best practice; impacts ratings, discoverability, or UX |
🟢 [OPTIONAL] | Nice to have |
Phase 1 — Developer Account & Identity
1.1 Apple Developer Program
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 1.1.1 | Apple Developer Program enrolled | [ ] | 🔴 BLOCKER | Account enrollment | $99/year. Individual or Organization. Card payment required. | ✅ Yes |
| 1.1.2 | D-U-N-S Number (Org accounts only) | [ ] | 🔴 BLOCKER | Text / registration | 9-digit number. Apply via Dun & Bradstreet. Takes 5–14 business days if new. | ✅ Yes (Org only) |
| 1.1.3 | Two-Factor Authentication enabled | [ ] | 🔴 BLOCKER | Account setting toggle | Must be enabled on the Apple ID used for developer account. | ✅ Yes |
| 1.1.4 | EU Digital Services Act (DSA) Trader Status | [ ] | 🔴 BLOCKER | Form in App Store Connect | Required for EU App Store distribution. Text fields: business name, address, contact info. | ✅ Yes (EU) |
1.2 App Identity
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 1.2.1 | App Name (final) | [ ] | 🔴 BLOCKER | Text input | Max 30 characters. No special characters that could cause confusion. Check trademark. Cannot use competitor names. | ✅ Yes |
| 1.2.2 | Bundle ID (com.company.appname) | [ ] | 🔴 BLOCKER | Text / reverse-domain string | Reverse-domain format. Lowercase, dots, hyphens only. Cannot be changed after first submission. Must match Xcode project exactly. | ✅ Yes |
| 1.2.3 | App ID registered in Apple Developer Portal | [ ] | 🔴 BLOCKER | Portal registration | Must match Bundle ID exactly. Created under Certificates, IDs & Profiles. | ✅ Yes |
| 1.2.4 | Primary App Category | [ ] | 🔴 BLOCKER | Dropdown select | Single selection from Apple's category list. Affects discoverability and age rating assessment. | ✅ Yes |
| 1.2.5 | Secondary App Category | [ ] | 🟢 OPTIONAL | Dropdown select | Optional second category. Separate from primary. | No |
| 1.2.6 | Age Rating (Content Questionnaire) | [ ] | 🔴 BLOCKER | Multi-question form | Must answer all questions honestly (violence, adult content, gambling, etc.). Generates rating automatically (4+, 9+, 12+, 17+). | ✅ Yes |
| 1.2.7 | Updated Age Rating Questions (2026) | [ ] | 🔴 BLOCKER | Multi-question form | Apple updated age rating questions in 2025/2026. Must respond by Jan 31, 2026 for existing apps (or before any update submission). | ✅ Yes |
Phase 2 — Technical Build Requirements
2.1 Xcode & SDK Requirements (Critical 2026 Updates)
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 2.1.1 | Built with Xcode 26 (or latest stable) | [ ] | 🔴 BLOCKER | Build tool | From April 28, 2026: must use iOS 26 SDK or later. Old Xcode = automatic rejection. macOS only. | ✅ Yes |
| 2.1.2 | iOS 26 SDK targeted (from April 28, 2026) | [ ] | 🔴 BLOCKER | IPHONEOS_DEPLOYMENT_TARGET | Minimum: iOS 26 SDK for new submissions after April 28, 2026. Check Apple's upcoming requirements page for exact date. | ✅ Yes |
| 2.1.3 | Deployment Target set (min supported iOS) | [ ] | 🟠 MANDATORY | Xcode project setting | Should support last 2 major iOS versions. Example: iOS 17+ acceptable currently. Cannot be lower than what Apple deems obsolete. | ✅ Yes |
| 2.1.4 | 64-bit architecture support | [ ] | 🔴 BLOCKER | Build setting | ARM64 required. Flutter handles this automatically. No 32-bit. | ✅ Yes |
| 2.1.5 | IPv6 network compatibility | [ ] | 🟠 MANDATORY | Code/network layer | Apple tests on IPv6-only networks. Must not use IPv4-only calls. Standard URLSession is fine. | ✅ Yes |
| 2.1.6 | No private / undocumented API usage | [ ] | 🔴 BLOCKER | Binary scan (automated by Apple) | Apple scans binary automatically. Flutter plugins can sometimes include private APIs — audit carefully. | ✅ Yes |
| 2.1.7 | App does not crash on launch | [ ] | 🔴 BLOCKER | QA testing | Test cold start on minimum 3 real devices including oldest supported iOS version. | ✅ Yes |
2.2 Signing & Certificates
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 2.2.1 | App Store Distribution Certificate (.p12) | [ ] | 🔴 BLOCKER | File upload (Keychain/Xcode) | .p12 file with password. Has expiry date — typically 1 year. Must be re-generated if expired. | ✅ Yes |
| 2.2.2 | App Store Distribution Provisioning Profile | [ ] | 🔴 BLOCKER | File / Xcode managed | Tied to App ID + Certificate. Must be "App Store Distribution" type (not Development/Ad Hoc). | ✅ Yes |
| 2.2.3 | Automatic Signing configured in Xcode | [ ] | 🟠 MANDATORY | Xcode project setting | Xcode can manage automatically if Apple Developer account is connected. Preferred for simplicity. | ✅ Yes |
| 2.2.4 | All Capability Entitlements configured | [ ] | 🟠 MANDATORY | Xcode Capabilities tab + Portal | Push Notifications, iCloud, Sign in with Apple, Background Modes — each needs entitlement registered in Portal AND Xcode. | ✅ Yes |
2.3 Info.plist & Permissions
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 2.3.1 | NSCameraUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required if app accesses camera. Text must clearly explain why. Vague = rejection. Max ~200 chars recommended. | Conditional |
| 2.3.2 | NSMicrophoneUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required if app accesses microphone. Clear purpose statement. | Conditional |
| 2.3.3 | NSLocationWhenInUseUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for foreground location access. | Conditional |
| 2.3.4 | NSLocationAlwaysAndWhenInUseUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for background location. Background location needs strong justification. | Conditional |
| 2.3.5 | NSPhotoLibraryUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | For reading photo library. | Conditional |
| 2.3.6 | NSPhotoLibraryAddUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | For saving to photo library (separate from reading). | Conditional |
| 2.3.7 | NSContactsUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for contacts access. | Conditional |
| 2.3.8 | NSFaceIDUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required if app uses Face ID / biometric. | Conditional |
| 2.3.9 | NSUserTrackingUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required if app uses ATT (App Tracking Transparency). Must explain tracking purpose clearly. | Conditional |
| 2.3.10 | NSHealthShareUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for HealthKit read access. | Conditional |
| 2.3.11 | NSHealthUpdateUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for HealthKit write access. | Conditional |
| 2.3.12 | NSCalendarsUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for calendar access. | Conditional |
| 2.3.13 | NSBluetoothAlwaysUsageDescription | [ ] | 🔴 BLOCKER | String in Info.plist | Required for Bluetooth. | Conditional |
| 2.3.14 | All unused permission keys removed | [ ] | 🟠 MANDATORY | Info.plist audit | Including a permission string for a feature you don't use = rejection. Audit and remove all unused keys. | ✅ Yes |
| 2.3.15 | Background Modes justified | [ ] | 🟠 MANDATORY | Xcode Capabilities | Background fetch, audio, location, VoIP — each requires clear business justification in review notes. | Conditional |
2.4 Versioning
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 2.4.1 | CFBundleShortVersionString (version) | [ ] | 🔴 BLOCKER | String in Info.plist | User-visible version. Format: 1.0.0. Must match App Store Connect version field. | ✅ Yes |
| 2.4.2 | CFBundleVersion (build number) | [ ] | 🔴 BLOCKER | String in Info.plist | Integer or dotted integer. Must increment with EVERY upload to TestFlight or App Store. Cannot reuse build numbers. | ✅ Yes |
| 2.4.3 | pubspec.yaml version matches (Flutter) | [ ] | 🔴 BLOCKER | version: 1.0.0+1 in pubspec | The +1 is the build number. Must match CFBundleVersion. | ✅ Yes (Flutter) |
2.5 Flutter-Specific Requirements
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 2.5.1 | flutter_launcher_icons package configured | [ ] | 🟠 MANDATORY | pubspec.yaml config + run command | Run flutter pub run flutter_launcher_icons before every release build. All icon sizes generated. | ✅ Yes |
| 2.5.2 | flutter_native_splash configured | [ ] | 🟡 RECOMMENDED | pubspec.yaml config | Consistent launch screen. Required behavior: no black flash on startup. | Recommended |
| 2.5.3 | Production Flutter flavor/scheme set up | [ ] | 🟡 RECOMMENDED | Build configuration | Separate prod flavor with prod API base URLs, Firebase project, RevenueCat keys. | Recommended |
| 2.5.4 | flutter build ipa --release tested | [ ] | 🔴 BLOCKER | CLI command | Test the actual release IPA. Debug builds behave very differently. Verify on TestFlight before App Store. | ✅ Yes |
| 2.5.5 | Flutter obfuscation configured | [ ] | 🟡 RECOMMENDED | --obfuscate --split-debug-info=<dir> | Hardens binary against reverse engineering. Keep debug symbols for crash symbolication. | Recommended |
| 2.5.6 | Platform channels tested on release build | [ ] | 🟠 MANDATORY | QA | Native method channels can behave differently in release mode (especially method not found errors). | ✅ Yes |
| 2.5.7 | All dependencies on stable channel | [ ] | 🟡 RECOMMENDED | pubspec.yaml | Avoid pre-release packages in production builds. | Recommended |
| 2.5.8 | RevenueCat / StoreKit integration tested (if subscriptions) | [ ] | 🔴 BLOCKER | SDK integration | Full purchase → receipt → entitlement unlock flow tested in sandbox. | Conditional |
2.6 Launch Screen
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 2.6.1 | LaunchScreen.storyboard configured | [ ] | 🔴 BLOCKER | Xcode storyboard / Flutter splash | Must exist. Cannot be missing. Cannot be all-black. Should match app branding. | ✅ Yes |
| 2.6.2 | No text or logos on launch screen (Apple preference) | [ ] | 🟡 RECOMMENDED | Design guideline | Apple recommends launch screen matches first screen of app. Logos/text technically allowed but not preferred. | Recommended |
Phase 3 — Store Listing Assets
3.1 App Icons
| # | Item | Status | Severity | Dimensions | File Specs | Mandatory? |
|---|---|---|---|---|---|---|
| 3.1.1 | App Store icon (1024×1024) | [ ] | 🔴 BLOCKER | 1024 × 1024 px | PNG, no alpha/transparency, no rounded corners (Apple applies mask), no interlacing. Max 500KB recommended. | ✅ Yes |
| 3.1.2 | All in-app icon sizes generated | [ ] | 🔴 BLOCKER | Various (20, 29, 40, 58, 60, 76, 80, 87, 120, 152, 167, 180 px) | Use flutter_launcher_icons or Xcode Asset Catalog. All sizes required. | ✅ Yes |
3.2 Screenshots
| # | Item | Status | Severity | Dimensions | File Specs | Mandatory? |
|---|---|---|---|---|---|---|
| 3.2.1 | iPhone 6.9" screenshots (iPhone 16 Pro Max) | [ ] | 🔴 BLOCKER | 1320 × 2868 px | JPEG or PNG. Required as of 2024 — this is now the primary screenshot slot. | ✅ Yes |
| 3.2.2 | iPhone 6.5" screenshots (iPhone 14 Plus/Pro Max) | [ ] | 🟡 RECOMMENDED | 1284 × 2778 px | Shown on older iPhones if 6.9" not set separately. | Recommended |
| 3.2.3 | iPhone 5.5" screenshots | [ ] | 🟢 OPTIONAL | 1242 × 2208 px | For older device compatibility. | No |
| 3.2.4 | iPad Pro 12.9" screenshots (6th gen) | [ ] | 🔴 BLOCKER (if iPad) | 2048 × 2732 px | Required if app supports iPad. | ✅ Yes (iPad) |
| 3.2.5 | iPad Pro 11" screenshots | [ ] | 🟢 OPTIONAL | 1668 × 2388 px | Optional additional iPad size. | No |
| 3.2.6 | Apple Watch screenshots | [ ] | 🟢 OPTIONAL | Various | Required only if app has a watchOS extension. | Conditional |
| 3.2.7 | Minimum 2, maximum 10 screenshots per slot | [ ] | 🔴 BLOCKER | — | Must have at least 2 screenshots. Max 10 per device size. | ✅ Yes |
Screenshot Content Rules:
- Must show actual app functionality (no mockups of features that don't exist)
- No pricing information in screenshots (Apple policy)
- No UI from a different OS (no Android UI elements)
- No misleading imagery or unsubstantiated claims
- Text overlays allowed but Apple reviewers check accuracy
3.3 App Preview Video
| # | Item | Status | Severity | Specs | Notes | Mandatory? |
|---|---|---|---|---|---|---|
| 3.3.1 | App Preview video | [ ] | 🟢 OPTIONAL | 15–30 seconds, MP4/MOV, recorded at device resolution | Must show actual app use — no voiceover marketing. Must be recorded on device or simulator. | No |
| 3.3.2 | Video resolution matches screenshot slot | [ ] | 🟠 MANDATORY (if video) | Must match device size | 6.9" preview: 886×1920 or 1290×2796. | Conditional |
3.4 Text Metadata
| # | Item | Status | Severity | Character Limit | Notes | Mandatory? |
|---|---|---|---|---|---|---|
| 3.4.1 | App Name | [ ] | 🔴 BLOCKER | Max 30 chars | Shown under icon in store. Include primary keyword naturally. No ALL CAPS. No misleading keywords. | ✅ Yes |
| 3.4.2 | Subtitle | [ ] | 🟠 MANDATORY | Max 30 chars | Shown in search results under name. Increases keyword surface area. High value field. | Recommended |
| 3.4.3 | Description | [ ] | 🔴 BLOCKER | Max 4000 chars | First 3 lines visible before "More". Most critical copy. No HTML supported. Cannot mention Android/Google Play. Must match actual app functionality. | ✅ Yes |
| 3.4.4 | Promotional Text | [ ] | 🟢 OPTIONAL | Max 170 chars | Shown above description. Can be updated without a new app review. Use for time-sensitive messaging. | No |
| 3.4.5 | Keywords | [ ] | 🟠 MANDATORY | Max 100 chars total | Comma-separated. No spaces after commas. Do not repeat words already in title/subtitle. Do not use competitor names. Do not use trademarked terms you don't own. | ✅ Yes |
| 3.4.6 | Support URL | [ ] | 🔴 BLOCKER | Valid URL | Must be a working, live URL. Not a placeholder. Apple reviewers check this. | ✅ Yes |
| 3.4.7 | Marketing URL | [ ] | 🟢 OPTIONAL | Valid URL | Optional app website or landing page. | No |
| 3.4.8 | Privacy Policy URL | [ ] | 🔴 BLOCKER | Valid URL | Required for ALL apps. Must be a live web page (not PDF). Must accurately describe data practices. | ✅ Yes |
| 3.4.9 | What's New (Release Notes) | [ ] | 🟠 MANDATORY | Max 4000 chars | Required for every update submission. Describe changes clearly. | ✅ Yes (updates) |
| 3.4.10 | Version Number | [ ] | 🔴 BLOCKER | e.g. 1.0.0 | Must match CFBundleShortVersionString in binary. | ✅ Yes |
| 3.4.11 | Copyright | [ ] | 🟠 MANDATORY | Text | Format: © 2026 Company Name. Shown on store listing. | ✅ Yes |
| 3.4.12 | Review Notes for Apple Reviewer | [ ] | 🟡 RECOMMENDED | Up to 4000 chars | Provide demo account credentials, explain non-obvious features, note any restricted features. Highly recommended to avoid rejection. | Recommended |
| 3.4.13 | Demo Account (login credentials) | [ ] | 🔴 BLOCKER (if login required) | Text | If app requires login, must provide working reviewer credentials. Account must have full feature access. No "demo" restricted accounts. | Conditional |
Phase 4 — Legal & Compliance
4.1 Privacy Policy
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 4.1.1 | Privacy policy hosted at live URL | [ ] | 🔴 BLOCKER | Web page, not PDF. Must be accessible at time of review. | ✅ Yes |
| 4.1.2 | All data types collected listed | [ ] | 🔴 BLOCKER | Name, email, device ID, location, usage data, etc. Must be comprehensive. | ✅ Yes |
| 4.1.3 | Third-party SDKs disclosed | [ ] | 🟠 MANDATORY | Firebase, RevenueCat, analytics SDKs — all data practices disclosed. | ✅ Yes |
| 4.1.4 | Data sharing disclosed | [ ] | 🟠 MANDATORY | Who data is shared with and why. | ✅ Yes |
| 4.1.5 | Data retention period stated | [ ] | 🟠 MANDATORY | How long data is kept. | ✅ Yes |
| 4.1.6 | User rights stated (GDPR/CCPA) | [ ] | 🟠 MANDATORY | Right to access, delete, correct, export data. | ✅ Yes |
| 4.1.7 | AI/external AI service disclosure (2026 new) | [ ] | 🔴 BLOCKER | New 2026 requirement. If app uses external AI services (OpenAI, Claude, Gemini, etc.), must disclose this in privacy policy AND get user consent before sending data. | ✅ Yes (if AI) |
4.2 App Privacy Nutrition Labels (App Store Connect)
| # | Item | Status | Severity | Input Type | Notes | Mandatory? |
|---|---|---|---|---|---|---|
| 4.2.1 | App Privacy section completed | [ ] | 🔴 BLOCKER | Multi-step form in App Store Connect | Under App → App Privacy. Must be completed before submitting for review. | ✅ Yes |
| 4.2.2 | "Data Used to Track You" declared | [ ] | 🔴 BLOCKER | Checkbox list | Any cross-app or cross-website tracking must be listed. | ✅ Yes |
| 4.2.3 | "Data Linked to You" declared | [ ] | 🔴 BLOCKER | Checkbox list | All data tied to user identity must be disclosed. | ✅ Yes |
| 4.2.4 | "Data Not Linked to You" declared | [ ] | 🔴 BLOCKER | Checkbox list | Analytics or crash data not tied to identity. | ✅ Yes |
| 4.2.5 | Labels match actual app behavior | [ ] | 🔴 BLOCKER | Cross-check with code | Apple verifies. Inconsistency = rejection and possible removal. | ✅ Yes |
| 4.2.6 | Third-party SDK data practices included | [ ] | 🟠 MANDATORY | Checkbox list | You are responsible for disclosing data collected by ALL SDKs in your app, not just your own code. | ✅ Yes |
4.3 App Tracking Transparency (ATT)
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 4.3.1 | ATT prompt implemented (if tracking) | [ ] | 🔴 BLOCKER | AppTrackingTransparency framework. iOS 14.5+. Must be called before any IDFA access. | Conditional |
| 4.3.2 | NSUserTrackingUsageDescription in Info.plist | [ ] | 🔴 BLOCKER | Clear purpose string. Cannot be vague ("for better ad experience"). | Conditional |
| 4.3.3 | AI service data consent (2026) | [ ] | 🔴 BLOCKER | New 2026: Must get user consent before sending personal data to third-party AI services. | ✅ Yes (if AI) |
4.4 Account Deletion
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 4.4.1 | In-app account deletion flow | [ ] | 🔴 BLOCKER | Required since June 2022. Must be in-app — not "email us to delete." Must delete account + data. | ✅ Yes (if accounts) |
| 4.4.2 | Account deletion deletes associated data | [ ] | 🔴 BLOCKER | Data must be purged from backend. Link to App Store subscription cancellation if subscriptions exist. | ✅ Yes (if accounts) |
4.5 Sign in with Apple
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 4.5.1 | Sign in with Apple offered | [ ] | 🔴 BLOCKER | Required if app offers any other third-party login (Google, Facebook, Twitter, etc.). Must be equally prominent. | Conditional |
| 4.5.2 | Sign in with Apple entitlement added | [ ] | 🔴 BLOCKER | Added in Xcode Capabilities + Apple Developer Portal. | Conditional |
4.6 Legal Compliance
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 4.6.1 | GDPR compliance (EU users) | [ ] | 🟠 MANDATORY | Consent management, data subject rights, DPA contact info. | ✅ Yes |
| 4.6.2 | COPPA compliance (under-13 users) | [ ] | 🔴 BLOCKER | If app targets or may be used by children. No behavioral advertising. Limited data collection. | Conditional |
| 4.6.3 | Kids Category compliance | [ ] | 🔴 BLOCKER | If in Kids category — no third-party analytics, no external links, no behavioral ads. | Conditional |
| 4.6.4 | Declared Age Range API (iOS 26+) | [ ] | 🟡 RECOMMENDED | New in iOS 26. Lets app access user's declared age range for age-appropriate experiences without collecting birthdate. | Recommended |
| 4.6.5 | Export compliance answered | [ ] | 🔴 BLOCKER | Standard HTTPS/TLS encryption = select "Exempt." Apps with additional encryption must complete BIS export form. | ✅ Yes |
| 4.6.6 | Content rights — original content confirmed | [ ] | 🟠 MANDATORY | You own or have rights to all content in the app. Checked in App Store Connect. | ✅ Yes |
| 4.6.7 | Terms of Service / EULA in-app | [ ] | 🟠 MANDATORY (if ToS) | User must affirmatively accept before using. Not pre-checked. | Conditional |
Phase 5 — Monetization Setup (If Applicable)
5.1 Apple In-App Purchases
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 5.1.1 | IAP products created in App Store Connect | [ ] | 🔴 BLOCKER | Form in App Store Connect → In-App Purchases | Product ID, Reference Name, Type (consumable/non-consumable/subscription), Price Tier, Localized display name + description. | ✅ Yes (if IAP) |
| 5.1.2 | Product IDs match app code exactly | [ ] | 🔴 BLOCKER | Text string | Case-sensitive. Must match string in code 100%. Cannot be changed after creation. Max 255 chars, alphanumeric + . + - + _. | ✅ Yes (if IAP) |
| 5.1.3 | IAP reviewer screenshot submitted | [ ] | 🔴 BLOCKER | Image upload in App Store Connect | Apple requires screenshot showing how IAP is presented to users. PNG/JPEG. | ✅ Yes (if IAP) |
| 5.1.4 | IAP review notes | [ ] | 🟡 RECOMMENDED | Text field | Explain what the purchase unlocks if not obvious from screenshot. | Recommended |
| 5.1.5 | StoreKit 2 integrated (or RevenueCat) | [ ] | 🟠 MANDATORY | SDK | StoreKit 2 preferred for iOS 16+. Test with Xcode StoreKit Testing config or Sandbox. | ✅ Yes (if IAP) |
| 5.1.6 | Sandbox test account created | [ ] | 🟠 MANDATORY | App Store Connect → Sandbox Testers | For testing IAP on real device without real charges. Different Apple ID from main account. | ✅ Yes (if IAP) |
| 5.1.7 | Restore Purchases button implemented | [ ] | 🟠 MANDATORY | UI button in app | Required by App Store guidelines for non-consumables and subscriptions. Must be visible/accessible. | ✅ Yes (if IAP) |
5.2 Subscriptions
| # | Item | Status | Severity | Field Type | Limits & Validation | Mandatory? |
|---|---|---|---|---|---|---|
| 5.2.1 | Subscription group created | [ ] | 🔴 BLOCKER | App Store Connect form | Required for upgrade/downgrade flows. All subscription tiers must be in the same group. | ✅ Yes (if sub) |
| 5.2.2 | Free trial period configured (if offered) | [ ] | 🟠 MANDATORY | Dropdown in App Store Connect | Duration options: 3 days, 1 week, 2 weeks, 1 month, 2 months, 3 months, 6 months, 1 year. | Conditional |
| 5.2.3 | Subscription terms shown in-app before purchase | [ ] | 🔴 BLOCKER | UI design | Guideline 3.1.2: Price, duration, auto-renewal terms must be shown to user BEFORE purchase confirmation. No exceptions. | ✅ Yes (if sub) |
| 5.2.4 | Cancellation instructions accessible in-app | [ ] | 🟠 MANDATORY | Settings / help section | Link to App Store subscription management OR clear instructions. | ✅ Yes (if sub) |
| 5.2.5 | Subscription status checked on app launch | [ ] | 🟠 MANDATORY | Code logic | Check current entitlement via StoreKit/RevenueCat on every app launch. Don't cache indefinitely. | ✅ Yes (if sub) |
| 5.2.6 | Billing grace period enabled | [ ] | 🟡 RECOMMENDED | App Store Connect toggle | Keeps user access during failed payment retry window. Good UX. | Recommended |
| 5.2.7 | Tax information submitted in App Store Connect | [ ] | 🟠 MANDATORY | Tax forms | Required before any paid sales. Varies by country — complete for all regions you sell in. | ✅ Yes (if paid) |
| 5.2.8 | Bank account / payout details added | [ ] | 🟠 MANDATORY | App Store Connect → Agreements, Tax, Banking | Required to receive revenue. Can take 3–5 business days to verify. | ✅ Yes (if paid) |
5.3 Pricing
| # | Item | Status | Severity | Field Type | Notes | Mandatory? |
|---|---|---|---|---|---|---|
| 5.3.1 | App base price set | [ ] | 🟠 MANDATORY (if paid) | Dropdown — price tier | Select from Apple's price tier system. Automatically converts to local currencies. | Conditional |
| 5.3.2 | Price by region reviewed | [ ] | 🟡 RECOMMENDED | Per-country override | Purchasing power varies. Consider lower tiers for emerging markets. | Recommended |
| 5.3.3 | Apple's 15–30% commission factored in | [ ] | 🟡 RECOMMENDED | Financial planning | 30% standard. 15% for Small Business Program (< $1M/year). 15% after 1 year continuous subscription. | Recommended |
Phase 6 — Testing & QA Gates
6.1 Functional Testing
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 6.1.1 | App launches without crash (cold start) | [ ] | 🔴 BLOCKER | Test on minimum 3 real devices. Apple reviewer will test this first. | ✅ Yes |
| 6.1.2 | Core user flows work end-to-end | [ ] | 🔴 BLOCKER | All main screens and happy paths. | ✅ Yes |
| 6.1.3 | Offline/no network handling | [ ] | 🟠 MANDATORY | No unhandled exceptions. Clear error messages. | ✅ Yes |
| 6.1.4 | Permission denial handled gracefully | [ ] | 🟠 MANDATORY | App must not crash if user denies any permission. Show appropriate fallback UI. | ✅ Yes |
| 6.1.5 | Background / foreground transitions | [ ] | 🟠 MANDATORY | App must not lose state or crash when backgrounded and reopened. | ✅ Yes |
| 6.1.6 | Push notifications tested | [ ] | 🟠 MANDATORY (if used) | Both foreground and background states. Test on real device — not simulator. | Conditional |
| 6.1.7 | Deep links tested | [ ] | 🟠 MANDATORY (if used) | Test from browser, iMessage, email. Test universal links AND custom URL schemes. | Conditional |
| 6.1.8 | Logout / login cycle | [ ] | 🟠 MANDATORY (if auth) | All state and cached data cleared properly on logout. | Conditional |
| 6.1.9 | Account deletion flow tested | [ ] | 🔴 BLOCKER (if accounts) | Full flow: in-app delete → backend data purge → confirmation. | Conditional |
| 6.1.10 | IAP full purchase flow in sandbox | [ ] | 🔴 BLOCKER (if IAP) | Purchase → receipt → entitlement unlock → restore flow. | Conditional |
| 6.1.11 | In-app review prompt does NOT appear on first launch | [ ] | 🟠 MANDATORY | Guideline: prompt after meaningful user action, not on launch. | Conditional |
6.2 Device & iOS Version Coverage
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 6.2.1 | Tested on latest iPhone (iPhone 16 / Dynamic Island) | [ ] | 🟠 MANDATORY | Dynamic Island, rounded corners, notch cutout. | ✅ Yes |
| 6.2.2 | Tested on iPhone SE (small screen 4.7") | [ ] | 🟡 RECOMMENDED | Common source of layout overflow issues. | Recommended |
| 6.2.3 | Tested on minimum iOS deployment target | [ ] | 🟠 MANDATORY | Real device preferred. Catch API availability issues. | ✅ Yes |
| 6.2.4 | Tested on latest iOS release | [ ] | 🟠 MANDATORY | Apple reviewers run latest iOS. | ✅ Yes |
| 6.2.5 | Tested on iPad (if iPad supported) | [ ] | 🟠 MANDATORY | iPad multitasking, split view, Stage Manager. | Conditional |
| 6.2.6 | Dark mode tested | [ ] | 🟡 RECOMMENDED | App should not look broken in dark mode. | Recommended |
| 6.2.7 | Dynamic Text / Accessibility sizes tested | [ ] | 🟡 RECOMMENDED | Text should not clip or overflow at large sizes. | Recommended |
6.3 Performance
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 6.3.1 | App startup time under 3 seconds | [ ] | 🟡 RECOMMENDED | Measure cold start on real device. Over 3s risks abandonment and review concerns. | Recommended |
| 6.3.2 | Memory leaks checked | [ ] | 🟡 RECOMMENDED | Use Xcode Instruments → Leaks, Allocations. | Recommended |
| 6.3.3 | 60fps scrolling / animations | [ ] | 🟡 RECOMMENDED | Check with Xcode Core Animation instrument. | Recommended |
| 6.3.4 | Release build performance profiled | [ ] | 🟠 MANDATORY | Always profile release build — debug builds are significantly slower. | ✅ Yes |
| 6.3.5 | App size optimized | [ ] | 🟡 RECOMMENDED | Flutter: use --split-debug-info. Aim under 50MB download size (100MB max limit for cellular download). | Recommended |
6.4 Security
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 6.4.1 | API keys not hardcoded in app binary | [ ] | 🔴 BLOCKER | Use environment variables, remote config, or backend proxy. Reviewers and bad actors can inspect binaries. | ✅ Yes |
| 6.4.2 | HTTPS enforced for all network calls | [ ] | 🟠 MANDATORY | ATS (App Transport Security) enforced by default on iOS. Do not disable NSAllowsArbitraryLoads without justification. | ✅ Yes |
| 6.4.3 | Auth tokens stored in Keychain | [ ] | 🟠 MANDATORY | Use flutter_secure_storage (wraps Keychain). Not UserDefaults or shared preferences. | ✅ Yes (if auth) |
| 6.4.4 | Sensitive data not logged in release | [ ] | 🟠 MANDATORY | Remove all print() / debugPrint() that output PII or tokens. | ✅ Yes |
| 6.4.5 | Certificate pinning considered | [ ] | 🟢 OPTIONAL | For high-security apps (banking, health). Adds complexity but valuable. | No |
6.5 TestFlight
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 6.5.1 | Internal TestFlight testing completed | [ ] | 🟠 MANDATORY | Upload to TestFlight, test with dev team before submitting to App Store. | ✅ Yes |
| 6.5.2 | External TestFlight beta (optional) | [ ] | 🟡 RECOMMENDED | Up to 10,000 external testers. Requires beta review by Apple (usually < 24h). | Recommended |
| 6.5.3 | All TestFlight feedback addressed | [ ] | 🟡 RECOMMENDED | At least 1 full beta cycle before submitting for App Store review. | Recommended |
| 6.5.4 | Crashlytics / Sentry monitoring active in TestFlight | [ ] | 🟠 MANDATORY | Know about crashes before app goes live. | ✅ Yes |
| 6.5.5 | APNs new server certificate updated (if push) | [ ] | 🔴 BLOCKER | Apple updated APNs server certificate in Feb 2025. Trust Store must include new SHA-2 Root: USERTrust RSA CA. | Conditional |
Phase 7 — Submission & Review
7.1 App Store Connect — Pre-Submission Checklist
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 7.1.1 | Binary uploaded via Xcode or Transporter | [ ] | 🔴 BLOCKER | macOS only. Cannot be done on Windows/Linux without CI (Codemagic, Bitrise, GitHub Actions). | ✅ Yes |
| 7.1.2 | All metadata fields completed | [ ] | 🔴 BLOCKER | Name, description, screenshots, keywords, URLs, privacy policy all filled. | ✅ Yes |
| 7.1.3 | Age rating questionnaire completed | [ ] | 🔴 BLOCKER | Including updated 2026 questions. | ✅ Yes |
| 7.1.4 | App Privacy nutrition label completed | [ ] | 🔴 BLOCKER | All data types, tracking, linked/unlinked to identity. | ✅ Yes |
| 7.1.5 | Export compliance declared | [ ] | 🔴 BLOCKER | HTTPS = Exempt. Custom encryption = declare. | ✅ Yes |
| 7.1.6 | Content rights declared | [ ] | 🟠 MANDATORY | "Do you own all rights to this content?" | ✅ Yes |
| 7.1.7 | IDFA/Advertising Identifier usage declared | [ ] | 🟠 MANDATORY | Even if only "serving ads" — must be checked. | ✅ Yes |
| 7.1.8 | Review notes + demo credentials added | [ ] | 🟡 RECOMMENDED | Dramatically reduces rejection risk for apps requiring login. | Recommended |
| 7.1.9 | Phased Release configured | [ ] | 🟡 RECOMMENDED | 7-day phased release: 1%→2%→5%→10%→20%→50%→100%. Can pause at any time if crash spike detected. | Recommended |
| 7.1.10 | Additional submission while prior in progress | [ ] | 🟢 OPTIONAL | New 2026: Apple now allows submitting additional items while another submission is in review. | No |
7.2 Review Timeline
| Phase | Typical Duration |
|---|---|
| Automated binary checks | Minutes |
| App Review queue | 24–72 hours (most apps) |
| New developer account first submission | May take up to 7 days |
| After rejection + resubmission | Clock restarts |
| TestFlight external beta review | < 24 hours usually |
7.3 Common Rejection Reasons (2026)
| # | Reason | How to Avoid |
|---|---|---|
| R1 | App crashes during review | Thorough TestFlight testing. Test on oldest supported iOS. |
| R2 | Broken Support URL or Privacy Policy URL | Check all URLs load correctly before submission. |
| R3 | Screenshots don't match actual app | Screenshots must show real app UI, not design mockups. |
| R4 | Missing NSXxxUsageDescription for permissions | Audit Info.plist — every permission key needs a string. |
| R5 | Sign in with Apple missing when other social login present | Implement SIWA before submitting if Google/Facebook login exists. |
| R6 | Subscription terms not clearly disclosed | Show price + duration + auto-renewal before purchase confirmation. |
| R7 | IAP not explained to reviewer | Add reviewer screenshot + notes explaining what purchase unlocks. |
| R8 | Login credentials not provided | Always include demo account in reviewer notes for login-required apps. |
| R9 | App offers insufficient value / "thin" app | Ensure meaningful functionality beyond a simple web view. |
| R10 | Metadata mentions Android / Google Play | Never mention competing platforms in description, screenshots, or keywords. |
| R11 | Private API detected | Run binary analysis. Audit all third-party plugins. |
| R12 | AI data collection not disclosed or consented | New 2026: disclose AI services and get consent. |
| R13 | Age rating questions not updated | Complete the new 2026 age rating questionnaire before submitting. |
Phase 8 — Post-Launch
8.1 Monitoring
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 8.1.1 | Crashlytics / Sentry live and receiving events | [ ] | 🟠 MANDATORY | Monitor from day 1. Set up crash rate alerts. | ✅ Yes |
| 8.1.2 | App Store Connect Analytics reviewed | [ ] | 🟡 RECOMMENDED | Impressions, conversions, sessions, retention. Review within first week. | Recommended |
| 8.1.3 | Crash-free rate target set | [ ] | 🟡 RECOMMENDED | Target: >99.5% crash-free sessions. Apple badges/features apps with high quality metrics. | Recommended |
8.2 Support Infrastructure
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 8.2.1 | Support email actively monitored | [ ] | 🟠 MANDATORY | Listed on App Store. Apple may also email here during review. | ✅ Yes |
| 8.2.2 | Support URL live and functional | [ ] | 🟠 MANDATORY | Must remain live. App can be removed if support URL goes dead. | ✅ Yes |
| 8.2.3 | In-app review prompt implemented | [ ] | 🟡 RECOMMENDED | in_app_review Flutter package. Prompt after positive action — not on launch. | Recommended |
| 8.2.4 | Respond to App Store reviews | [ ] | 🟡 RECOMMENDED | Especially negative reviews. Shows engagement. Cannot offer incentives for positive reviews. | Recommended |
8.3 Legal Ongoing
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 8.3.1 | Privacy policy kept up to date | [ ] | 🟠 MANDATORY | Update any time data practices change. | ✅ Yes |
| 8.3.2 | GDPR data deletion requests handled | [ ] | 🟠 MANDATORY | Process within 30 days of request. | ✅ Yes |
| 8.3.3 | Apple Developer Program renewed annually | [ ] | 🔴 BLOCKER | Non-renewal = app removed from App Store. | ✅ Yes |
| 8.3.4 | Distribution certificate renewed before expiry | [ ] | 🔴 BLOCKER | Expires ~1 year. Create new one and update provisioning profiles before submitting updates. | ✅ Yes |
8.4 Update Cadence
| # | Item | Status | Severity | Notes | Mandatory? |
|---|---|---|---|---|---|
| 8.4.1 | Version numbering strategy defined | [ ] | 🟠 MANDATORY | Semantic versioning: major.minor.patch. Build number must always increment. | ✅ Yes |
| 8.4.2 | SDK requirement deadline tracked (April 28, 2026) | [ ] | 🔴 BLOCKER | All app updates submitted after April 28, 2026 must use iOS 26 SDK. | ✅ Yes |
| 8.4.3 | Forced update mechanism (if needed) | [ ] | 🟢 OPTIONAL | Firebase Remote Config can enforce minimum app version for breaking API changes. | No |
Quick Summary — Top 10 iOS Blockers in 2026
1. Build with Xcode 26 + iOS 26 SDK (mandatory from April 28, 2026)
2. Complete App Privacy Nutrition Labels accurately
3. NSXxxUsageDescription for EVERY permission key used
4. Sign in with Apple if any third-party login exists
5. Subscription terms shown BEFORE purchase confirmation
6. In-app account deletion (required since 2022)
7. Demo account credentials in reviewer notes
8. Screenshots match actual app UI (1320×2868 px for 6.9" slot)
9. AI service usage disclosed + user consent obtained (new 2026)
10. Updated age rating questionnaire completed (new 2026 questions)
Reference sources: Apple Developer Documentation, Apple App Store Review Guidelines, Apple Upcoming Requirements page, Apple Developer News — April 2026