| name | review-readiness-check |
| description | Detects review-blocking configuration issues including sub-1.0 version numbers, beta in app name, staging endpoints, and missing demo credentials that prevent reviewers from evaluating the app, violating Guidelines 2.1 and 2.3. |
Skill: Review Readiness Check
Purpose
Detects review-blocking configuration issues including sub-1.0 version numbers, beta/alpha in app name, staging endpoints, and missing demo credentials that prevent reviewers from evaluating the app, violating Guidelines 2.1 and 2.3.
Apple Guideline
- Primary: 2.1 โ Performance: App Completeness
- Related: 2.3 โ Performance: Accurate Metadata
- Reference:
references/guidelines/2-performance.md
Real-World Rejection Cases
-
Case: App version showing "0.1" in App Store submission โ reviewer treated as beta/incomplete
Source: mobiloud.com/blog/avoid-app-rejected-apple
Root cause: Sub-1.0 version numbers signal incomplete app to reviewers โ Apple's review team interprets 0.x versions as pre-release/beta software not ready for the App Store
-
Case: App requiring login with no demo account provided โ reviewer couldn't access any features โ rejected
Source: Apple Developer Forums (Guideline 2.1 enforcement; reviewer requirement documented in App Review guidelines)
Root cause: If app requires login, demo credentials must be in review notes โ reviewers will not create real accounts and will reject if they cannot access core functionality
-
Case: App used SMS-based OTP for login โ App Store reviewer's test device could not receive SMS to the developer's phone number โ reviewer was locked out and rejected the app
Source: Apple Developer Forums thread/125961
Root cause: Reviewers cannot receive SMS codes tied to the developer's phone. Apps with SMS OTP must provide a demo account that bypasses OTP, or document a working alternative in review notes
-
Case: App referenced an IAP product still in "Waiting for Review" status in App Store Connect โ reviewer saw "item not available" on purchase โ rejected
Source: RevenueCat (revenuecat.com/blog/engineering/app-store-rejections-and-how-to-avoid-them)
Root cause: All IAP products referenced by the app must be in "Ready to Submit" status before submission. Any unapproved IAP appears unavailable to reviewers
-
Case: App displayed a mandatory update dialog immediately on launch blocking all app content โ reviewer downloaded the submission binary and could not proceed past the update screen โ rejected under 2.1
Source: Apple Developer Forums (multiple developer reports)
Root cause: The App Store reviewer evaluates the exact binary submitted โ a forced-update gate that requires downloading a newer version from the App Store means the submitted build is inaccessible. The submitted build must be fully functional as-is; forced update prompts must never block access to core functionality during review
Trigger
Invoke on any iOS/macOS project before App Store submission to check submission configuration readiness.
Inputs
| Name | Type | Default | Description |
|---|
project_root | path | cwd | iOS/macOS project root |
shared_context | object | nil | Pre-collected context from appstore-full-audit Phase 1 |
Actions
Phase 1: Context Collection
Skip this phase if shared_context is provided.
Glob **/*.pbxproj โ locate the Xcode project file.
Glob **/Info.plist โ locate Info.plist.
Glob **/*.swift โ collect Swift source files for network configuration.
Glob REVIEW_NOTES*|review_notes*|AppStoreReviewInfo*|ReviewNotes* โ locate review notes documentation.
Phase 2: Checks
-
Marketing version number
Read project.pbxproj โ search for MARKETING_VERSION.
If value starts with 0. โ ๐ HIGH. Version numbers starting with 0 signal beta status; use 1.0 or higher for initial App Store submissions.
-
Beta/alpha/test in app display name
Read Info.plist โ check CFBundleDisplayName value.
If value contains "beta", "alpha", "debug", "test", "demo" (case-insensitive) โ ๐ HIGH. App names containing these words signal an incomplete build.
-
Staging or localhost endpoints
Grep pattern "localhost"|"127\.0\.0\.1"|"staging\."|"\.dev\." in **/*.swift and configuration files.
Any match in a base URL constant or API configuration โ ๐ HIGH. Submissions must use production endpoints.
-
Demo credentials documented
Glob REVIEW_NOTES*|review_notes*|AppStoreReviewInfo*|ReviewNotes* โ check if file exists.
If absent: Grep "login"|"signIn"|"signUp"|"createAccount" in **/*.swift โ if login is required, flag โ ๐ HIGH. Demo credentials must accompany any login-required submission.
-
HTTP (non-HTTPS) API endpoints
Grep pattern "http://" in **/*.swift โ filter for API base URL constants.
Any non-HTTPS production endpoint โ ๐ HIGH. App Transport Security requires HTTPS by default.
-
Forced update gate on launch
Grep pattern forceUpdate|force_update|ForceUpdate|minimumVersion|minVersion|min_version|mustUpdate in **/*.swift.
For each match, Read surrounding context โ if an update prompt is shown unconditionally at launch with no way to dismiss โ ๐ด CRITICAL. The submitted binary must be fully functional as-is; blocking access pending an App Store update locks out the reviewer entirely.
Phase 3: Output
Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.
Output Format
## Review Readiness Check โ Findings
### ๐ด CRITICAL โ Guaranteed rejection
- [ ] TODO: Remove or make dismissible the forced-update gate โ submitted binary must be fully accessible to reviewer without requiring an App Store update โ `AppUpdateManager.swift:22` โ Guideline 2.1
### ๐ HIGH โ Very likely rejection
- [ ] TODO: Change MARKETING_VERSION from 0.9 to 1.0 or higher before submission โ sub-1.0 versions are treated as beta โ `MyApp.xcodeproj/project.pbxproj` โ Guideline 2.1
- [ ] TODO: Rename app display name โ remove "Beta" from CFBundleDisplayName โ `Info.plist` โ Guideline 2.1
- [ ] TODO: Replace staging base URL with production URL โ `NetworkConstants.swift:8` โ Guideline 2.1
- [ ] TODO: Add REVIEW_NOTES.md with demo credentials โ app requires login but no credentials are documented for reviewers โ Guideline 2.1
- [ ] TODO: Change API base URL from http:// to https:// โ `APIConfig.swift:4` โ Guideline 2.1
### ๐ก MEDIUM โ Possible rejection
- [ ] TODO: Verify all App Store Connect metadata URLs (support, marketing, privacy policy) return 200 before submission
### ๐ข LOW โ Best practice
- [ ] TODO: Run a pre-submission checklist: version โฅ 1.0, all URLs live, demo credentials documented, no staging endpoints active in release scheme
Tools Used
Glob, Grep, Read
Constraints
- Read-only. No file edits.
- No network calls.
- Skip Phase 1 if
shared_context is provided by orchestrating agent.
- Works on Swift, Objective-C, React Native, Flutter projects.
Quick Commands
Run these in your project root to check manually:
!grep -rn "MARKETING_VERSION" . --include="*.pbxproj" | head -3
!find . -name "Info.plist" -not -path "*/Pods/*" | head -1 | xargs plutil -convert json -o - | python3 -c "import sys,json; d=json.load(sys.stdin); print('Display Name:', d.get('CFBundleDisplayName', d.get('CFBundleName','?')))"
!grep -rn "localhost\|127\.0\.0\.1\|staging\.\|\.dev\." . --include="*.swift" --include="*.plist" | grep -iv "comment\|test\|localhost_not"
!grep -rn "DEBUG\|STAGING\|DEVELOPMENT" . --include="*.xcconfig" --include="*.plist"
Swift Anti-Pattern Reference
examples/swift/QualityPatterns.swift
Detection Steps
-
Find target files
- Glob:
**/Info.plist, **/*.swift, **/fastlane/
-
Search for rejection patterns
- Read
Info.plist โ check CFBundleShortVersionString for beta, test, 0.0, 0.1
- Read
Info.plist โ check CFBundleName / CFBundleDisplayName for beta, test, debug
- Grep
localhost\|127\.0\.0\.1\|staging\.\|\.dev\. in Swift constants/configuration files
- Check
fastlane/metadata/review_information/ exists with demo credentials
-
Determine verdict
beta or test in bundle version/name โ ๐ HIGH (Guideline 2.1)
- Hardcoded staging/localhost URL in production code โ ๐ HIGH
- No demo account credentials in fastlane review notes โ ๐ก MEDIUM (if login required)
- All checks pass โ ๐ข pass
-
Report
- Exact value of
CFBundleShortVersionString and CFBundleName
- File path + line of any hardcoded staging URL
- Fix: Set version to a release number (e.g.,
1.0.0); use build configuration to switch URLs