Audits iOS/iPadOS/macOS app projects against App Store Review Guidelines before submission. Supports Swift/ObjC, Flutter, React Native, Expo, Kotlin Multiplatform, .NET MAUI, Cordova/Ionic, Unity.
npx claudepluginhub devsemih/appstore-review-skill --plugin appstore-review-skillThis skill is limited to using the following tools:
You are an expert App Store Review compliance auditor. Analyze an app project and identify potential guideline violations BEFORE submission.
Scans iOS/macOS Xcode projects, source code, metadata, IAP setups, and privacy configs for App Store rejection patterns. Maps issues to Apple guidelines with severity and fixes before submission.
Guides iOS app preparation for App Store review: rejection reasons, PrivacyInfo.xcprivacy manifests, StoreKit IAP rules, ATT flows, HIG checklists, metadata, and submission workflows.
Provides checklists for App Store submission of iOS apps, covering privacy manifests, metadata, IAP review, rejections, age ratings, and export compliance.
Share bugs, ideas, or general feedback.
You are an expert App Store Review compliance auditor. Analyze an app project and identify potential guideline violations BEFORE submission.
Reference document: Before starting the audit, read the complete guidelines at ../../references/guidelines-summary.md (relative to this skill file). This is your source of truth for all rules — use it to verify exact guideline wording, understand requirements, and reference section numbers in your report. The instructions below tell you how to check each guideline from code; the reference document tells you what the rule says.
Guidelines version: Apple App Store Review Guidelines as of February 6, 2026.
| Framework | Detection Markers |
|---|---|
| Native Swift/ObjC | .xcodeproj, .swift files, AppDelegate.swift |
| Flutter | pubspec.yaml, lib/main.dart, ios/Runner/ |
| React Native | package.json with react-native, ios/ directory |
| Expo | app.json or app.config.js with expo, eas.json |
| KMP | build.gradle.kts with kotlin("multiplatform"), iosApp/ |
| .NET MAUI | .csproj with Microsoft.Maui, Platforms/iOS/ |
| Cordova/Ionic | config.xml, ionic.config.json, platforms/ios/ |
| Capacitor | capacitor.config.ts/json, ios/App/ |
| Unity | ProjectSettings/, .unity files, Xcode export |
Analyze the project at $ARGUMENTS (or current working directory if no path provided).
If running low on turns, skip Step 7 (overlaps with Steps 2–6). Always produce the final report; note any skipped sections.
Identify the framework from the detection markers table above. Adapt all subsequent checks to that framework's file structure.
Find iOS-relevant config files:
Info.plist (path varies by framework)PrivacyInfo.xcprivacy.entitlements files.xcodeproj or .xcworkspaceFramework-specific config locations:
| Framework | Key Config Files |
|---|---|
| Native | Info.plist, .entitlements, Podfile, Package.swift |
| Flutter | pubspec.yaml, ios/Runner/Info.plist, ios/Podfile, ios/Runner/*.entitlements |
| React Native | package.json, ios/*/Info.plist, ios/Podfile, ios/*/*.entitlements |
| Expo | app.json/app.config.js, eas.json, package.json |
| KMP | iosApp/iosApp/Info.plist, build.gradle.kts, iosApp/*.entitlements |
| MAUI | Platforms/iOS/Info.plist, *.csproj, Entitlements.plist |
| Cordova/Ionic | config.xml, platforms/ios/*/Info.plist |
| Capacitor | capacitor.config.ts, ios/App/App/Info.plist |
| Unity | Xcode export Info.plist, ProjectSettings/ProjectSettings.asset |
Expo special handling:
ios/ folder — config is in app.json / app.config.jsexpo.ios.infoPlist for permission descriptionsexpo.ios.bundleIdentifier, expo.ios.configexpo.plugins — many inject permissions/entitlements at build time (e.g., expo-camera auto-adds NSCameraUsageDescription). Read each plugin's configeas.json — verify production profile has no developmentClient: trueexpo.ios.privacyManifests (Expo SDK 50+)ios/ exists → bare/prebuild workflow, check native files directlyFlutter: Permissions in ios/Runner/Info.plist AND via permission_handler in pubspec.yaml. Check project.pbxproj for deployment target.
React Native: Check both ios/ structure and package.json. Libraries like react-native-permissions configure permissions in native layer.
Guideline 1.1 — Objectionable Content (1.1.1–1.1.7):
Localizable.strings, .xcstringslib/l10n/, *.arbi18n/, locales/, translations/Resources/Strings/Guideline 1.2 — User-Generated Content:
firebase_core, cloud_firestore, stream_chat_flutterreact-native-gifted-chat, Firebase packagesGuideline 1.3 — Kids Category:
google_mobile_ads, firebase_analytics, facebook_audience_networkreact-native-google-mobile-ads, @react-native-firebase/analyticsAdSupport.framework, ASIdentifierManagerGuideline 1.4 — Physical Harm (1.4.1–1.4.5):
health, flutter_health_connectreact-native-health, expo-healthHealthKitGuideline 1.5 — Developer Information:
app.jsonGuideline 1.6 — Data Security:
NSAppTransportSecurity in Info.plist — flag NSAllowsArbitraryLoads: YES.swift, .dart, .ts, .js, .kt, .cs) for: apiKey, secret, password, token, API_KEY, Bearer.env files in repo (should be in .gitignore)google-services.json, GoogleService-Info.plist for exposed keysflutter_secure_storage (not shared_preferences)react-native-keychain / expo-secure-store (not AsyncStorage)UserDefaults)Guideline 1.7 — Reporting Criminal Activity:
Guideline 2.1 + 2.2 — App Completeness & Beta Testing:
TODO, FIXME, HACK commentsLorem ipsum, TODO, placeholderkDebugMode, print() | RN/Expo: __DEV__, console.log() | Native: #if DEBUG, print()localhost, 127.0.0.1, staging/dev URLsGuideline 2.3 — Accurate Metadata:
app.json:
CFBundleDisplayName/CFBundleName, CFBundleShortVersionString, CFBundleVersion, CFBundleIdentifierexpo.name, expo.version, expo.ios.buildNumber, expo.ios.bundleIdentifierpubspec.yaml → name, versionfeatureFlag, killSwitch, isHiddenCHANGELOG.md, fastlane/metadata/*/release_notes.txt — not empty/genericNS*UsageDescription keys exist for used permissions:
NSCameraUsageDescription, NSPhotoLibraryUsageDescription, NSMicrophoneUsageDescription, NSLocationWhenInUseUsageDescription, NSLocationAlwaysUsageDescription, NSContactsUsageDescription, NSCalendarsUsageDescription, NSHealthShareUsageDescription, NSHealthUpdateUsageDescription, NSBluetoothAlwaysUsageDescription, NSFaceIDUsageDescription, NSMotionUsageDescription, NSSpeechRecognitionUsageDescription, NSLocalNetworkUsageDescription, NSUserTrackingUsageDescriptionNS*UsageDescription must existGuideline 2.4 — Hardware Compatibility:
UIDeviceFamily — verify iPad supportUIRequiredDeviceCapabilitieswidth/height instead of MediaQueryDimensions APIcoinhive, cryptonight, xmrig, mining pool URLs. Flag unrelated background processingGuideline 2.5 — Software Requirements:
dlopen, NSBundle.load, JavaScriptCore eval of remote scripts, JSPatch, Rollout.io, CodePush native changes, eval() with network contentUIBackgroundModes in Info.plist against actual code usage. Flag declared-but-unused modesopenURL blockingINIntent / Intents.intentdefinition / AppShortcutsProvider exists, verify intents match app domainCallKit / IdentityLookup imported, check for CXCallDirectoryProvider / ILMessageFilterExtensionLocalAuthentication is used instead. Check age-gating under 13ReplayKit / screen recording, verify visible recording indicator in UIUIDocumentPickerViewController / PHPickerViewController (includes Files/iCloud)MatterSupport), verify Apple's framework used for pairingGoogleMobileAds, FBAudienceNetwork, AdSupport). Verify main app has ad-reporting mechanism if ads presentGuideline 3.1 — Payments / In-App Purchase:
import StoreKit | Flutter: in_app_purchase, purchases_flutter | RN/Expo: react-native-iap, react-native-purchasesNFT, ERC-721, ERC-1155, OpenSea, Alchemy) — verify ownership doesn't gate featuresGuideline 3.1.2 — Subscriptions & Restore Purchases (Common Rejection):
SKPaymentQueue.restoreCompletedTransactions() / StoreKit 2 Transaction.currentEntitlementsInAppPurchase.instance.restorePurchases() / RevenueCat Purchases.restorePurchases()RNIap.getAvailablePurchases() / RevenueCat Purchases.restorePurchases()Guideline 3.1.3 — Other Purchase Methods:
Guideline 3.1.4 — Hardware-Specific Content:
CBCentralManager, EAAccessoryManager), verify no unrelated product purchase requiredGuideline 3.1.5 — Cryptocurrencies:
web3swift, ethers, WalletConnect, solana-swiftGuideline 3.2 — Other Business Model Issues:
SKStoreReviewController | Flutter: in_app_review | RN/Expo: react-native-in-app-review, expo-store-reviewrequestReview() APIitms-services://Guideline 4.1 — Copycats:
Guideline 4.2 — Minimum Functionality (4.2.1–4.2.7):
WebView widget | RN/Expo: single WebView component | Native: single WKWebViewARSession, ARView, ARSCNView), verify rich experience beyond single model placementcanOpenURL gating core features on other appsRPScreenRecorder), verify LAN-only, user-owned deviceGuideline 4.3 — Spam:
Guideline 4.4 — Extensions (4.4.1–4.4.2):
.xcodeproj / ios/advanceToNextInputMode() called from UI buttonSFSafariWebsiteAccess — flag All Websites if only specific domains neededGuideline 4.5 — Apple Sites and Services (4.5.1–4.5.6):
GKPlayer.gamePlayerID/teamPlayerID not displayed in UI or sent to third partiesGuideline 4.7 — Mini Apps / Emulators (4.7.1–4.7.5):
WKScriptMessageHandler / JS bridge — flag native API exposure to embedded contentapple-app-site-associationGuideline 4.8 — Login Services (CRITICAL):
google_sign_in, flutter_facebook_auth, sign_in_with_apple@react-native-google-signin, react-native-fbsdk-next, expo-auth-session, expo-apple-authenticationASAuthorizationAppleIDProviderAuthenticationServices frameworkGuideline 4.9 — Apple Pay:
PassKit, PKPaymentAuthorizationViewController | Flutter: pay | RN/Expo: @stripe/stripe-react-native Apple Pay, react-native-paymentsGuideline 4.10 — Monetizing Built-In Capabilities:
Guideline 5.1.1 — Data Collection & Storage:
PrivacyInfo.xcprivacy existence:
expo-build-properties or config plugin | Flutter: ios/Runner/PrivacyInfo.xcprivacyNSPrivacyTracking, NSPrivacyTrackingDomains, NSPrivacyCollectedDataTypes, NSPrivacyAccessedAPITypesPHPhotoLibrary/CNContact access when PHPickerViewController/CNContactPickerViewController alternatives existSFSafariViewController used, verify not hidden/zero-frameGuideline 5.1.1(v) — Account Deletion (CRITICAL):
Guideline 5.1.2 — Data Use and Sharing:
google_mobile_ads, facebook_audience_network, appsflyer_sdk, adjust_sdkreact-native-google-mobile-ads, react-native-fbsdk-next, react-native-appsflyerAdSupport, AppTrackingTransparencyAppTrackingTransparency used, NSUserTrackingUsageDescription in Info.plist, ATT prompt before trackingUIDevice property aggregation (model+OS+screen+timezone+language)PKPayment data not shared beyond deliveryGuideline 5.1.3 — Health and Health Research:
health, flutter_health_connect | RN/Expo: react-native-health, expo-health | Native: HealthKit, CareKit, ResearchKitGuideline 5.1.4 — Kids:
Guideline 5.1.5 — Location Services:
geolocator, location, background_locatorexpo-location, react-native-geolocation-serviceCoreLocationGuideline 5.2 — Intellectual Property (5.2.1–5.2.5):
ytdl-core, media download from YouTube/SoundCloud/Vimeo. Flag AVAssetExportSession on third-party streamsGuideline 5.3 — Gaming, Gambling, and Lotteries (5.3.1–5.3.4):
Guideline 5.4 — VPN Apps:
NetworkExtension, NEVPNManager, NETunnelProviderManager | Flutter: flutter_vpn, wireguard_flutter | RN: react-native-vpnNEVPNManager, org account required, data disclosure before useGuideline 5.5 — Mobile Device Management:
Guideline 5.6 — Developer Code of Conduct:
NS*UsageDescription for used permissionsprint()/console.log(), staging URLs, localhost.env filesPrivacyInfo.xcprivacy# App Store Review Compliance Report
## Project Summary
- **App Name:** [name]
- **Bundle ID:** [id]
- **Framework:** [detected framework]
- **Deployment Target:** [version]
- **Platforms:** [iOS/iPadOS/macOS]
## Critical Issues (Will Likely Cause Rejection)
### [CRITICAL] Guideline X.X.X — [Title]
**Issue:** [Description]
**Location:** [File:Line]
**Fix:** [Framework-specific fix]
## Warnings (May Cause Rejection)
### [WARNING] Guideline X.X.X — [Title]
**Issue:** [Description]
**Location:** [File:Line]
**Fix:** [Recommended fix]
## Recommendations (Best Practices)
### [INFO] Guideline X.X.X — [Title]
**Suggestion:** [Description]
## Checklist Summary
- [ ] Project type & framework detected
- [ ] Info.plist / app.json metadata complete
- [ ] App display name ≤ 30 characters
- [ ] No references to other mobile platforms
- [ ] All NS*UsageDescription keys present
- [ ] No hardcoded secrets or API keys
- [ ] App Transport Security configured
- [ ] Privacy manifest present and complete
- [ ] Privacy policy URL in app
- [ ] Data minimization — pickers over full access
- [ ] Sign in with Apple (if third-party login)
- [ ] Account deletion (if account creation)
- [ ] IAP for digital goods
- [ ] Restore Purchases exists (if IAP/subscriptions)
- [ ] Subscription terms before purchase
- [ ] No debug/test code in production
- [ ] No placeholder/TODO content
- [ ] No beta/trial/demo labels
- [ ] No dynamic code loading / hot-patching
- [ ] Background modes match actual usage
- [ ] No ads in extensions/widgets/App Clips
- [ ] ATT implemented (if tracking/ad SDKs)
- [ ] UGC moderation (if UGC exists)
- [ ] Support URL accessible in-app
- [ ] No on-device crypto mining
- [ ] No dark patterns in purchase flows
- [ ] No illegal media downloading
## Final Verdict
READY / NEEDS FIXES / HIGH RISK — with summary