| 2.1 App Completeness | Crash on reviewer's device/OS, dead-end flow, placeholder content, ad fails to load → blank space, debug/test ad shown in the prod build | Run the build on a clean device + the oldest supported OS. Ensure ads degrade gracefully (no empty frame on no-fill). TF builds should carry prod (not test) ad IDs — verify real ads render, not test units. No <TRANSLATE> / lorem strings. |
| 2.3.1 Hidden features | Shipping dormant code / hidden toggles reviewers can reach | No DEBUG-only surfaces (NearWin hooks) reachable in Release. |
| 2.3.3 Screenshots | Screenshots don't match the actual app, wrong dimensions, contain device frames Apple disallows, alpha channel | Do not upload snapshot-test baselines directly — they have an alpha channel + wrong dims (use your screenshot-generation pipeline). Use real device/sim captures at exact spec sizes. |
| 2.3.10 Irrelevant metadata | Mentioning Android / "also on Google Play", other platform names in description/keywords | Strip platform references from all 7 locales' metadata. |
| 3.1.1 In-App Purchase | Remove-Ads unlock sold outside IAP; no "Restore Purchases" control; price/benefit unclear | Remove-Ads must be StoreKit IAP (it is — [[monetization-sdk-integration]]). Apple's wording is "you should have a restore mechanism," but it is enforced in practice as mandatory — ship a visible Restore Purchases button; non-consumable must restore on reinstall. |
| 4.3(a)/(b) Spam / saturation | Highest latent risk — saturated genres (puzzle, utility) face 4.3(b) "indistinguishable from what's already available" risk. (Apple's enumerated 4.3(b) examples are flashlight/sound-effects/wallpaper/timer/fortune-telling — puzzle games aren't named; the risk is inferred from saturation, not an explicit callout.) A thin clone gets bounced as spam. | Lead with genuine differentiation (design system, content hub, Game Center, cross-platform). Distinct app name/icon/screenshots per app; never ship two near-identical binaries under different names (4.3(a) = same app under multiple Bundle IDs). |
| 4.0 / 4.2 Minimum functionality | Too simple, feels like a web wrapper or template | Native features (haptics, Game Center, iCloud resume, widgets if any) demonstrate platform depth. |
| 5.1.1(v) Account deletion / data | App "supports account creation" but offers no in-app deletion path | Apple's text triggers the deletion requirement only for apps that "support account creation". If the app has no app-specific account-creation flow (identity via iCloud / Game Center), 5.1.1(v) likely doesn't apply — confirm for your app. But Apple publishes NO explicit iCloud/Game-Center exemption, so don't assert one as fact. Still: provide a way to clear the user's CloudKit data + a reachable privacy-policy URL. If rejected on 5.1.1(v), reply to Review that the app creates no app-specific account and data-clearing is available, rather than claiming a blanket exemption. |
| 5.1.1 Privacy policy | Missing/unreachable privacy policy URL in ASC + in-app | Privacy policy URL set in App Privacy + reachable; covers ads (AdMob) + analytics data. |
| 5.1.2 Data Use — ATT | The AdMob trap. App accesses ASIdentifierManager.advertisingIdentifier (IDFA) or presents the ATT prompt via UMP but lacks NSUserTrackingUsageDescription, or never shows the prompt at all | ATT is required when the app accesses IDFA (ASIdentifierManager.advertisingIdentifier) or presents the ATT prompt via UMP. AdMob can serve limited/non-personalized ads without accessing IDFA — in that case ATT is not required (though UMP/GDPR consent may still apply). When ATT is required: NSUserTrackingUsageDescription present in all 7 locales, ATT prompt shown via UMP before personalized ads. Ensure each new app in a multi-app repo has its own ATT primer coordinator component — it is a submission blocker if missing. If you do NOT access IDFA, declare so and don't link to it. Note: reviewers sometimes cite 2.1 (Information Needed) instead of 5.1.2 when they simply can't find where the prompt fires — the sim-verify checklist item below covers both. |
| Privacy-label parity | App Privacy "nutrition" answers in ASC contradict PrivacyInfo.xcprivacy / actual SDK behavior (AdMob collects identifiers + usage data) | ASC App Privacy answers must match the committed PrivacyInfo.xcprivacy and AdMob's declared collection. Keep them in sync ([[apple-three-piece-analytics]]). |
| Age rating / 1.3 | Ads can serve mature content but rating says 4+ | Set AdMob max ad content rating appropriately; age rating must cover ad content. |
| 2.5.x / export compliance | Build held "Processing" pending the encryption/export-compliance answer | Answer export compliance in ASC (uses standard crypto only) — user-owned, see your TestFlight upload workflow footgun. |