@forvibe/cli 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "name": "@forvibe/cli",
3
- "version": "1.1.1",
3
+ "version": "2.0.0",
4
4
  "description": "Forvibe CLI - AI-powered project analyzer for App Store automation",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "forvibe": "./dist/index.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsup src/index.ts --format esm --dts --clean && mkdir -p dist/review && cp -r src/review/rag-data dist/review/",
10
+ "build": "tsup src/index.ts --format esm --dts --clean && mkdir -p dist/engine && cp -r src/engine/data dist/engine/",
11
11
  "dev": "tsup src/index.ts --format esm --watch",
12
12
  "start": "node dist/index.js",
13
13
  "typecheck": "tsc --noEmit",
14
14
  "lint": "eslint src/",
15
+ "test": "vitest run",
16
+ "sync:rulepack": "node scripts/sync-rulepack.mjs",
15
17
  "prepublishOnly": "npm run build",
16
18
  "release": "npm run build && npm publish --access public",
17
19
  "release:dry": "npm run build && npm publish --access public --dry-run"
@@ -46,7 +48,8 @@
46
48
  "@types/node": "^22.13.0",
47
49
  "@types/plist": "^3.0.5",
48
50
  "tsup": "^8.4.0",
49
- "typescript": "^5.7.0"
51
+ "typescript": "^5.7.0",
52
+ "vitest": "^4.1.10"
50
53
  },
51
54
  "engines": {
52
55
  "node": ">=18"
@@ -1,282 +0,0 @@
1
- [
2
- {
3
- "id": "stripe-payment-digital-goods",
4
- "guidelineNumber": "3.1.1",
5
- "guidelineName": "In-App Purchase - Payments",
6
- "category": "business",
7
- "rejectionReason": "Your app uses a third-party payment system (Stripe) for digital content that must use In-App Purchase.",
8
- "whatDeveloperDid": "Integrated Stripe checkout to sell premium digital features like custom themes, advanced filters, and exclusive content within the app. Digital goods and services consumed within the app must use Apple's In-App Purchase system.",
9
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your app uses a third-party payment mechanism (Stripe) for digital content, features, or services that are consumed within the app. Per App Store Review Guidelines, apps offering digital goods or services for consumption within the app must use In-App Purchase. Please implement StoreKit for all digital content purchases.",
10
- "fix": "Replaced Stripe checkout with Apple's StoreKit 2 for all digital goods purchases. Stripe was kept only for physical goods/services not consumed within the app (if applicable). Implemented IAP products in App Store Connect for all premium features.",
11
- "outcome": "approved-after-fix",
12
- "keywords": ["stripe", "iap", "in-app-purchase", "digital-goods", "payment", "storekit"],
13
- "behavioralSignals": ["Stripe checkout for digital content", "credit card form for premium features", "third-party payment for in-app content", "non-IAP digital purchase"],
14
- "year": 2023
15
- },
16
- {
17
- "id": "missing-restore-purchases-button",
18
- "guidelineNumber": "3.1.2",
19
- "guidelineName": "Subscriptions",
20
- "category": "business",
21
- "rejectionReason": "Your app does not include a mechanism to restore previously purchased subscriptions.",
22
- "whatDeveloperDid": "Implemented a subscription paywall but did not include a 'Restore Purchases' button. Users who reinstalled the app or switched devices had no way to restore their active subscriptions without re-purchasing.",
23
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: Your app does not include a 'Restore Purchases' mechanism. Apps that offer auto-renewable subscriptions must include a restore mechanism to allow users to restore their previously purchased subscriptions on a new device or after reinstalling the app.",
24
- "fix": "Added a clearly visible 'Restore Purchases' button on the subscription/paywall screen. Implemented the SKPaymentQueue.restoreCompletedTransactions() (or StoreKit 2 equivalent) to restore active subscriptions. Also added a restore option in the app settings.",
25
- "outcome": "approved-after-fix",
26
- "keywords": ["restore-purchases", "subscription", "iap", "paywall", "storekit"],
27
- "behavioralSignals": ["no restore button on paywall", "unable to restore subscriptions", "missing restore mechanism", "subscription screen without restore option"],
28
- "year": 2024
29
- },
30
- {
31
- "id": "subscription-auto-renew-terms-missing",
32
- "guidelineNumber": "3.1.2",
33
- "guidelineName": "Subscriptions",
34
- "category": "business",
35
- "rejectionReason": "Your app does not clearly display auto-renewable subscription terms before the purchase is initiated.",
36
- "whatDeveloperDid": "Displayed a subscription paywall with pricing and a 'Subscribe' button but did not include the required auto-renewal terms, such as the subscription duration, price per period, and that the subscription automatically renews unless cancelled at least 24 hours before the end of the current period.",
37
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: Your app does not clearly display the following required subscription information before the user completes the purchase: the price and duration of the subscription, that payment will be charged to the iTunes Account, that the subscription automatically renews unless auto-renew is turned off at least 24 hours before the end of the current period, and links to your Privacy Policy and Terms of Use.",
38
- "fix": "Added all required subscription terms directly on the paywall screen in legible text. Included: price per period, subscription duration, auto-renewal disclosure, cancellation instructions, and links to Privacy Policy and Terms of Use. The terms are displayed before the subscribe button so users see them before purchasing.",
39
- "outcome": "approved-after-fix",
40
- "keywords": ["subscription", "auto-renew", "terms", "disclosure", "paywall", "cancellation"],
41
- "behavioralSignals": ["no auto-renewal terms displayed", "subscribe button without terms", "missing cancellation instructions", "paywall without legal disclosures"],
42
- "year": 2024
43
- },
44
- {
45
- "id": "external-payment-link-digital-content",
46
- "guidelineNumber": "3.1.1",
47
- "guidelineName": "In-App Purchase - Payments",
48
- "category": "business",
49
- "rejectionReason": "Your app contains a link that directs users to an external payment mechanism for digital content.",
50
- "whatDeveloperDid": "Included a button or link in the app labeled 'Upgrade to Premium' that opened the developer's website pricing page where users could purchase premium digital features via Stripe or PayPal, bypassing Apple's IAP system.",
51
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your app includes a link that directs users to an external mechanism for purchases that should be made through In-App Purchase. Specifically, tapping 'Upgrade to Premium' opens a web page where users can purchase premium features. Apps may not include buttons, external links, or other calls to action that direct users to purchasing mechanisms other than IAP for digital content.",
52
- "fix": "Removed the external payment link entirely. Replaced the web-based upgrade flow with StoreKit In-App Purchase. If eligible for the External Link Account Entitlement (reader apps, music streaming, etc.), applied for the entitlement with proper commission arrangements.",
53
- "outcome": "approved-after-fix",
54
- "keywords": ["external-link", "payment", "website", "iap-bypass", "digital-content", "external-purchase"],
55
- "behavioralSignals": ["upgrade button opens website", "external payment URL", "web-based purchase flow", "link to pricing page"],
56
- "year": 2023
57
- },
58
- {
59
- "id": "iap-product-fetch-failure-production",
60
- "guidelineNumber": "3.1.1",
61
- "guidelineName": "In-App Purchase",
62
- "category": "business",
63
- "rejectionReason": "Your In-App Purchase products failed to load during review.",
64
- "whatDeveloperDid": "IAP products worked correctly in the sandbox testing environment but failed to load during App Review. The products were not in the correct status in App Store Connect (they were still 'Waiting for Review' or 'Missing Metadata'), causing StoreKit to return empty product arrays.",
65
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: We were unable to purchase the In-App Purchase products in your app. When we attempted to view your subscription options, no products were displayed. Please ensure your IAP products are properly configured and in the correct status.",
66
- "fix": "Ensured all IAP products were in 'Ready to Submit' status in App Store Connect before submitting the app binary. Verified product IDs matched exactly between the app code and App Store Connect. Submitted the IAP products for review alongside the app binary. Added error handling UI to show a message and retry button when products fail to load.",
67
- "outcome": "approved-after-fix",
68
- "keywords": ["iap", "storekit", "product-fetch", "sandbox", "app-store-connect", "in-app-purchase"],
69
- "behavioralSignals": ["IAP products not loading", "empty product list", "subscription options blank", "StoreKit returns no products"],
70
- "year": 2024
71
- },
72
- {
73
- "id": "subscription-price-mismatch",
74
- "guidelineNumber": "3.1.2",
75
- "guidelineName": "Subscriptions",
76
- "category": "business",
77
- "rejectionReason": "The subscription price displayed in your app does not match the price configured in App Store Connect.",
78
- "whatDeveloperDid": "Hardcoded the subscription price as '$4.99/month' in the app UI, but the actual price in App Store Connect was set to $9.99/month. The mismatch was caught during review when the reviewer compared the displayed price with the StoreKit payment sheet price.",
79
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: The subscription price displayed in your app ($4.99/month) does not match the price set in App Store Connect ($9.99/month). The pricing information displayed to users must accurately reflect the actual purchase price.",
80
- "fix": "Removed all hardcoded prices from the app UI. Instead, used StoreKit's Product.displayPrice property to dynamically fetch and display the current price from App Store Connect. This also ensures correct pricing is shown across different currencies and regions.",
81
- "outcome": "approved-after-fix",
82
- "keywords": ["price-mismatch", "subscription", "hardcoded-price", "storekit", "pricing", "display-price"],
83
- "behavioralSignals": ["different price in UI vs payment sheet", "hardcoded price strings", "price doesn't match App Store Connect", "static pricing display"],
84
- "year": 2023
85
- },
86
- {
87
- "id": "free-trial-locks-immediately",
88
- "guidelineNumber": "3.1.2",
89
- "guidelineName": "Subscriptions",
90
- "category": "business",
91
- "rejectionReason": "Your app offers no functionality without a paid subscription and the free trial provides no usable experience.",
92
- "whatDeveloperDid": "Created an app where all content was behind a paywall. The app offered a '7-day free trial' but immediately required payment information and locked users into a subscription. There was no lite/free tier to explore the app's functionality before committing to a purchase.",
93
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: Your app locks users into a subscription immediately with no way to experience the app's core functionality before purchasing. Apps should provide some level of access or a meaningful free experience so users can evaluate the app before subscribing.",
94
- "fix": "Added a limited free tier that allows users to access basic features without subscribing. Users can create up to 3 items, view content with ads, and explore the app's core functionality. The premium subscription removes limits and ads. Also ensured the free trial doesn't require payment information upfront.",
95
- "outcome": "approved-after-fix",
96
- "keywords": ["free-trial", "paywall", "no-free-tier", "subscription-required", "locked-content"],
97
- "behavioralSignals": ["app unusable without payment", "immediate paywall on launch", "no free functionality", "forced subscription to use app"],
98
- "year": 2023
99
- },
100
- {
101
- "id": "loot-box-no-probability-disclosure",
102
- "guidelineNumber": "3.1.1",
103
- "guidelineName": "In-App Purchase",
104
- "category": "business",
105
- "rejectionReason": "Your app offers randomized virtual items for purchase (loot boxes) without disclosing the probability of receiving each type of item.",
106
- "whatDeveloperDid": "Built a mobile game with gacha/loot box mechanics where players could purchase virtual item packs with random contents using IAP, but did not disclose the drop rates or probability of receiving each rarity tier of items.",
107
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your app offers loot boxes or other mechanisms that provide randomized virtual items for purchase but does not disclose the odds of receiving each type of item to the user prior to purchase. Apps offering such mechanisms must include the probability of each type of item before the user commits to the purchase.",
108
- "fix": "Added a 'Drop Rates' information button next to every loot box purchase option. The button displays a clear breakdown of probabilities for each item rarity tier (e.g., Common: 60%, Rare: 25%, Epic: 10%, Legendary: 5%). This information is shown before the purchase confirmation.",
109
- "outcome": "approved-after-fix",
110
- "keywords": ["loot-box", "gacha", "probability", "drop-rates", "randomized-items", "disclosure"],
111
- "behavioralSignals": ["randomized item purchases", "loot box without odds", "gacha mechanic", "no probability information displayed"],
112
- "year": 2023
113
- },
114
- {
115
- "id": "tipping-feature-stripe-askaloo",
116
- "guidelineNumber": "3.1.1",
117
- "guidelineName": "In-App Purchase - Payments",
118
- "category": "business",
119
- "rejectionReason": "Your app uses Stripe for a tipping/donation feature for digital content creators, which must use In-App Purchase.",
120
- "whatDeveloperDid": "Askaloo (a Q&A platform) implemented a tipping feature using Stripe where users could tip content creators directly via credit card payments within the app, bypassing Apple's IAP system for what Apple classified as digital content consumption.",
121
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your app uses a third-party payment mechanism (Stripe) for tips/donations to content creators. Tips for digital content or services consumed within the app are considered digital goods and must use In-App Purchase. Please implement IAP for all tipping functionality.",
122
- "fix": "Replaced Stripe tipping with Apple's In-App Purchase consumable items for tip amounts. Created IAP products for different tip tiers ($1, $5, $10, $25). While Apple takes its commission on IAP transactions, this was the only way to keep the tipping feature in the app.",
123
- "outcome": "approved-after-fix",
124
- "keywords": ["tipping", "stripe", "donations", "iap", "content-creators", "digital-tips"],
125
- "behavioralSignals": ["tip button using Stripe", "credit card payment for tips", "non-IAP tipping", "third-party payment for digital content"],
126
- "year": 2021
127
- },
128
- {
129
- "id": "white-label-payment-app-rejection",
130
- "guidelineNumber": "3.2.2",
131
- "guidelineName": "Other Business Model Issues - Unacceptable",
132
- "category": "business",
133
- "rejectionReason": "Your app appears to be a white-label or template app that is not sufficiently differentiated.",
134
- "whatDeveloperDid": "Submitted a payment processing app that was a white-labeled version of a payment platform SDK. Multiple nearly identical apps from different business accounts used the same codebase with only branding differences (logo, colors, business name).",
135
- "whatAppleSaid": "Guideline 3.2.2 - Business - Other Business Model Issues - Unacceptable: Your app is a white-label version of another app. We have identified multiple apps with the same binary that differ only in branding. Creating multiple apps from a template or app generation service is considered spam and is not permitted on the App Store.",
136
- "fix": "Instead of publishing separate white-label apps for each business, consolidated into a single app with multi-tenant support. Each business gets their own branded experience within the single app through configuration. Alternatively, if each business has significantly unique features, ensured each version has meaningful functional differences beyond just branding.",
137
- "outcome": "approved-after-fix",
138
- "keywords": ["white-label", "template-app", "duplicate", "spam", "multi-tenant", "app-generation"],
139
- "behavioralSignals": ["identical app with different branding", "template-generated app", "same binary different logos", "multiple similar apps from same codebase"],
140
- "year": 2023
141
- },
142
- {
143
- "id": "hardcoded-pricing-not-matching-asc",
144
- "guidelineNumber": "3.1.2",
145
- "guidelineName": "Subscriptions",
146
- "category": "business",
147
- "rejectionReason": "Hardcoded pricing in your app does not match the prices configured in App Store Connect.",
148
- "whatDeveloperDid": "Displayed hardcoded pricing strings throughout the app (e.g., 'Premium: $2.99/mo') that were set during development. When the pricing was later changed in App Store Connect to $4.99/mo, the hardcoded strings were not updated, creating a price mismatch.",
149
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: We noticed that the pricing displayed in your app does not match the actual subscription pricing in App Store Connect. Your app shows '$2.99/month' but the configured price is '$4.99/month'. Please ensure pricing accuracy.",
150
- "fix": "Replaced all hardcoded price strings with dynamic pricing fetched from StoreKit. Used Product.displayPrice to show localized, accurate pricing that automatically reflects the current App Store Connect configuration and the user's local currency.",
151
- "outcome": "approved-after-fix",
152
- "keywords": ["hardcoded-pricing", "price-mismatch", "storekit", "dynamic-pricing", "subscription"],
153
- "behavioralSignals": ["static price strings in UI", "price doesn't match payment sheet", "hardcoded dollar amounts", "pricing inconsistency"],
154
- "year": 2024
155
- },
156
- {
157
- "id": "subscription-stuck-in-review-limbo",
158
- "guidelineNumber": "3.1.2",
159
- "guidelineName": "Subscriptions",
160
- "category": "business",
161
- "rejectionReason": "Your subscription products are still in review and cannot be tested.",
162
- "whatDeveloperDid": "Submitted an app update that referenced new IAP subscription products, but the products were submitted separately and were still pending review. The app binary was approved but the subscriptions remained in 'Waiting for Review' status for weeks, preventing the update from being published.",
163
- "whatAppleSaid": "Your app has been approved, but the In-App Purchase products associated with this version are still in review. Your app update cannot be released until all associated IAP products are also approved. Please wait for the IAP review to complete.",
164
- "fix": "For future submissions, ensured IAP products were submitted and approved before or simultaneously with the app binary. Contacted App Review via the Resolution Center to expedite the IAP review. Used the 'Submit with next app update' option in App Store Connect to link IAP products to the app submission.",
165
- "outcome": "approved-after-fix",
166
- "keywords": ["iap-review", "subscription-limbo", "pending-review", "app-store-connect", "iap-status"],
167
- "behavioralSignals": ["app approved but IAP pending", "subscription products in review", "update blocked by IAP review", "IAP waiting for review"],
168
- "year": 2023
169
- },
170
- {
171
- "id": "wrong-iap-language-rejection",
172
- "guidelineNumber": "3.1.1",
173
- "guidelineName": "In-App Purchase",
174
- "category": "business",
175
- "rejectionReason": "Your In-App Purchase product metadata language does not match the primary language of your app.",
176
- "whatDeveloperDid": "Configured IAP product names and descriptions in English in App Store Connect, but the app's primary language and storefront was set to Japanese. The IAP purchase sheet displayed English text in a Japanese-language app, creating an inconsistent user experience.",
177
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your In-App Purchase product names and descriptions are in English, but your app's primary language is Japanese. Please localize your IAP product metadata to match the primary language of your app for each storefront where it is available.",
178
- "fix": "Added Japanese localizations for all IAP product names and descriptions in App Store Connect. Used the App Store Connect localization features to provide product metadata in all languages the app supports.",
179
- "outcome": "approved-after-fix",
180
- "keywords": ["iap-localization", "language-mismatch", "metadata", "localization", "storefront"],
181
- "behavioralSignals": ["IAP text in wrong language", "English products in non-English app", "localization mismatch", "purchase sheet language inconsistent"],
182
- "year": 2022
183
- },
184
- {
185
- "id": "external-purchase-link-in-error-message",
186
- "guidelineNumber": "3.1.1",
187
- "guidelineName": "In-App Purchase - Payments",
188
- "category": "business",
189
- "rejectionReason": "Your app includes a link to an external purchase mechanism in an error message.",
190
- "whatDeveloperDid": "When a user hit a feature limit, the app displayed an error message saying 'You've reached the free limit. Upgrade at https://example.com/pricing to unlock unlimited access.' This URL led to a web checkout page with Stripe payment, bypassing IAP.",
191
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your app directs users to an external purchase mechanism in an error message. Specifically, when reaching a feature limit, the app displays a URL to your website's pricing page. Apps may not direct users to external purchase mechanisms for digital content, even in error messages or alerts.",
192
- "fix": "Removed the external URL from the error message. Replaced it with a button that opens the in-app subscription/purchase screen powered by StoreKit IAP. The error message now reads 'You've reached the free limit. Tap Upgrade to unlock unlimited access.' with an IAP-powered upgrade flow.",
193
- "outcome": "approved-after-fix",
194
- "keywords": ["external-link", "error-message", "iap-bypass", "pricing-url", "upgrade-link"],
195
- "behavioralSignals": ["URL in error message", "external pricing link", "web checkout reference in alert", "upgrade URL pointing to website"],
196
- "year": 2023
197
- },
198
- {
199
- "id": "paypal-checkout-premium-features",
200
- "guidelineNumber": "3.1.1",
201
- "guidelineName": "In-App Purchase - Payments",
202
- "category": "business",
203
- "rejectionReason": "Your app uses PayPal to sell premium digital features that must use In-App Purchase.",
204
- "whatDeveloperDid": "Integrated PayPal checkout to sell premium digital features like ad removal, additional storage, and advanced editing tools within a photo editing app.",
205
- "whatAppleSaid": "Guideline 3.1.1 - Business - Payments - In-App Purchase: Your app uses PayPal as a payment mechanism for digital content and features consumed within the app. Specifically, the 'Remove Ads' and 'Pro Editing Tools' purchases use PayPal checkout. Digital goods must be purchased through In-App Purchase.",
206
- "fix": "Removed PayPal integration for all digital goods. Implemented StoreKit In-App Purchase for the 'Remove Ads' (non-consumable) and 'Pro Tools' (subscription) products. PayPal can only be kept for physical goods or services delivered outside the app.",
207
- "outcome": "approved-after-fix",
208
- "keywords": ["paypal", "digital-goods", "iap", "payment", "premium-features", "ad-removal"],
209
- "behavioralSignals": ["PayPal checkout for digital features", "non-IAP payment for ad removal", "PayPal SDK for premium content", "third-party payment for in-app features"],
210
- "year": 2022
211
- },
212
- {
213
- "id": "business-model-change-re-review",
214
- "guidelineNumber": "3.2",
215
- "guidelineName": "Other Business Model Issues",
216
- "category": "business",
217
- "rejectionReason": "Your app's business model has changed significantly, triggering a full re-review.",
218
- "whatDeveloperDid": "An app that was previously approved as a free utility added a subscription paywall in an update that locked core features behind payment. Apple flagged this as a significant business model change and conducted a thorough re-review, questioning whether the app provided enough value to justify the subscription.",
219
- "whatAppleSaid": "Guideline 3.2 - Business - Other Business Model Issues: Your app has undergone a significant business model change from a free utility to a paid subscription service. We need to re-evaluate whether the app's functionality justifies the subscription pricing and whether existing users are adequately served by the new model.",
220
- "fix": "Grandfathered existing users into the premium features they previously had for free. Added a meaningful free tier with core functionality intact. Ensured the subscription provided clear additional value beyond what was previously free. Provided detailed notes in the resolution center explaining the business model change.",
221
- "outcome": "approved-after-fix",
222
- "keywords": ["business-model", "re-review", "subscription-change", "free-to-paid", "paywall-addition"],
223
- "behavioralSignals": ["previously free features now paid", "new paywall in update", "core features locked behind subscription", "business model pivot"],
224
- "year": 2023
225
- },
226
- {
227
- "id": "icloud-storage-monetization",
228
- "guidelineNumber": "3.1.3",
229
- "guidelineName": "Other Purchase Methods",
230
- "category": "business",
231
- "rejectionReason": "Your app charges users for iCloud storage sync which is a system-level capability.",
232
- "whatDeveloperDid": "Created a notes app that locked iCloud sync behind a paid subscription. While the app stored data locally for free, accessing your own data across devices via iCloud required purchasing the premium subscription.",
233
- "whatAppleSaid": "Guideline 3.1.3 - Business - Payments: Your app charges users for iCloud sync functionality, which leverages system-level capabilities. You should not create a purchase to gate access to Apple system features that users expect as standard functionality.",
234
- "fix": "Made basic iCloud sync available to all users for free. Restructured the subscription to provide value through advanced features (collaboration, advanced organization, export options) rather than gating system-level sync functionality.",
235
- "outcome": "approved-after-fix",
236
- "keywords": ["icloud", "sync", "system-features", "monetization", "storage", "gating"],
237
- "behavioralSignals": ["iCloud sync behind paywall", "charging for system feature", "sync requires subscription", "basic functionality gated"],
238
- "year": 2022
239
- },
240
- {
241
- "id": "charging-for-system-capabilities",
242
- "guidelineNumber": "3.2.2",
243
- "guidelineName": "Other Business Model Issues - Unacceptable",
244
- "category": "business",
245
- "rejectionReason": "Your app charges for access to built-in iOS capabilities.",
246
- "whatDeveloperDid": "Built an app that charged a subscription fee to enable features that are essentially wrappers around built-in iOS capabilities like the flashlight, compass, and level tool, without adding meaningful additional value.",
247
- "whatAppleSaid": "Guideline 3.2.2 - Business - Other Business Model Issues: Your app charges users for functionality that duplicates built-in iOS capabilities (flashlight, compass, level) without providing sufficient additional value or unique features. Apps should not monetize basic system functionality.",
248
- "fix": "Added significant unique value beyond the system capabilities: custom lighting modes, measurement history with export, AR-based measurements, and professional calibration tools. The subscription was repositioned around these genuinely unique features rather than the basic system functionality wrappers.",
249
- "outcome": "approved-after-fix",
250
- "keywords": ["system-capabilities", "built-in-features", "monetization", "insufficient-value", "system-wrapper"],
251
- "behavioralSignals": ["charging for flashlight", "paywall on system features", "wrapper around built-in tools", "basic iOS features behind subscription"],
252
- "year": 2023
253
- },
254
- {
255
- "id": "missing-subscription-management-instructions",
256
- "guidelineNumber": "3.1.2",
257
- "guidelineName": "Subscriptions",
258
- "category": "business",
259
- "rejectionReason": "Your app does not include instructions for how to manage or cancel a subscription.",
260
- "whatDeveloperDid": "Implemented subscription IAP but did not include any information in the app about how users can manage their subscription, view renewal dates, or cancel through iOS Settings.",
261
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: Your app does not include information about how to manage subscriptions. You must provide a link or instructions within the app that direct users to their subscription management settings where they can manage or cancel their subscription.",
262
- "fix": "Added a 'Manage Subscription' button in the app settings that deep-links to the iOS subscription management page (using UIApplication.open(URL(string: 'https://apps.apple.com/account/subscriptions')!)). Also added text explaining how to cancel and when the next renewal date is.",
263
- "outcome": "approved-after-fix",
264
- "keywords": ["subscription-management", "cancellation", "manage-subscription", "subscription-settings", "user-instructions"],
265
- "behavioralSignals": ["no cancel instructions", "no subscription management link", "missing renewal information", "no way to manage subscription in app"],
266
- "year": 2024
267
- },
268
- {
269
- "id": "no-free-tier-all-content-paywalled",
270
- "guidelineNumber": "3.1.2",
271
- "guidelineName": "Subscriptions",
272
- "category": "business",
273
- "rejectionReason": "Your app requires a subscription with no way to use the app without payment.",
274
- "whatDeveloperDid": "Launched an app with a hard paywall that showed the subscription screen immediately on launch with no dismiss button. Users could not access any part of the app without purchasing a subscription first, with no free trial or lite functionality.",
275
- "whatAppleSaid": "Guideline 3.1.2 - Business - Payments - Subscriptions: Your app requires a subscription purchase to access any content or functionality, with no free tier, trial, or sample content available. Users should be able to evaluate the app and experience some functionality before being required to purchase.",
276
- "fix": "Added a dismissible paywall with a 'Continue with Free' option. Created a free tier with limited but meaningful functionality (3 sessions per day, basic features). Added a 7-day free trial option for the full premium experience. The paywall is shown after the user has had a chance to experience the app.",
277
- "outcome": "approved-after-fix",
278
- "keywords": ["hard-paywall", "no-free-tier", "forced-subscription", "paywall-blocking", "subscription-required"],
279
- "behavioralSignals": ["paywall on launch with no dismiss", "no free content available", "subscription required to enter app", "no trial or lite mode"],
280
- "year": 2024
281
- }
282
- ]
@@ -1,212 +0,0 @@
1
- [
2
- {
3
- "id": "missing-demo-account-credentials",
4
- "guidelineNumber": "2.1",
5
- "guidelineName": "App Completeness",
6
- "category": "performance",
7
- "rejectionReason": "We were unable to review your app because no demo account credentials were provided.",
8
- "whatDeveloperDid": "Submitted an app that requires login to access core functionality but did not provide demo account credentials in the App Review Information section of App Store Connect. The reviewer could not sign in and therefore could not review the app.",
9
- "whatAppleSaid": "Guideline 2.1 - Performance - App Completeness: We are unable to complete the review of your app because we need a demo account to fully access your app's features. Please provide demo account credentials (username and password) in the App Review Information section of App Store Connect.",
10
- "fix": "Created a dedicated demo/review account with full access to all features. Added the username and password in App Store Connect > App Information > App Review Information > Sign-in required. Included notes describing which features to test and any special setup instructions.",
11
- "outcome": "approved-after-fix",
12
- "keywords": ["demo-account", "login", "credentials", "reviewer-access", "app-review-information"],
13
- "behavioralSignals": ["app requires login", "no demo credentials provided", "reviewer can't access features", "empty App Review Information"],
14
- "year": 2024
15
- },
16
- {
17
- "id": "demo-account-2fa-sms-service",
18
- "guidelineNumber": "2.1",
19
- "guidelineName": "App Completeness",
20
- "category": "performance",
21
- "rejectionReason": "The demo account requires SMS-based two-factor authentication that the reviewer cannot complete.",
22
- "whatDeveloperDid": "Provided demo account credentials but the account required SMS-based 2FA. The verification code was sent to the developer's phone number, and the Apple reviewer in California had no way to receive or enter the code.",
23
- "whatAppleSaid": "Guideline 2.1 - Performance - App Completeness: We were unable to log in to your app with the provided demo credentials. The account requires SMS verification and we are unable to receive the verification code. Please provide a demo account that can be fully accessed without additional verification steps or provide a way for us to complete the verification.",
24
- "fix": "Created a review-specific account with 2FA disabled. Alternatively, if 2FA cannot be disabled: set up a shared email account where the reviewer can receive verification codes, or use TOTP-based 2FA and share the TOTP secret/QR code in the review notes so the reviewer can generate codes themselves.",
25
- "outcome": "approved-after-fix",
26
- "keywords": ["demo-account", "2fa", "sms", "verification", "reviewer-access", "authentication"],
27
- "behavioralSignals": ["2FA on demo account", "SMS code required for login", "reviewer can't receive verification code", "authentication barrier for review"],
28
- "year": 2024
29
- },
30
- {
31
- "id": "support-url-no-contact-info",
32
- "guidelineNumber": "2.3",
33
- "guidelineName": "Accurate Metadata",
34
- "category": "performance",
35
- "rejectionReason": "Your support URL does not provide a way for users to contact you.",
36
- "whatDeveloperDid": "Provided a support URL in App Store Connect that linked to a generic company homepage, a blank page, or a page without any contact form, email address, phone number, or other way for users to get support.",
37
- "whatAppleSaid": "Guideline 2.3 - Performance - Accurate Metadata: The support URL you provided does not include any contact information or mechanism for users to reach you for support. The support URL must provide a way for users to contact you with questions or issues about your app.",
38
- "fix": "Created a dedicated support page with a contact form, support email address, and FAQ section. The page is accessible without login and provides clear ways for users to report issues and get help. Updated the support URL in App Store Connect.",
39
- "outcome": "approved-after-fix",
40
- "keywords": ["support-url", "contact-info", "metadata", "customer-support", "help-page"],
41
- "behavioralSignals": ["support URL is company homepage", "no contact form on support page", "support page has no email", "broken or empty support URL"],
42
- "year": 2023
43
- },
44
- {
45
- "id": "apple-requiring-video-demonstration",
46
- "guidelineNumber": "2.1",
47
- "guidelineName": "App Completeness",
48
- "category": "performance",
49
- "rejectionReason": "We need a video demonstration to understand how your app works.",
50
- "whatDeveloperDid": "Submitted an app with hardware-dependent features (Bluetooth device pairing, AR experiences, IoT integration, or features requiring specific real-world conditions) that the Apple reviewer could not test in their office environment.",
51
- "whatAppleSaid": "Guideline 2.1 - Performance - App Completeness: We are unable to fully evaluate your app's functionality because it requires specific hardware or real-world conditions we cannot replicate. Please provide a video that demonstrates the app's complete functionality, including the features that require external hardware or specific conditions.",
52
- "fix": "Recorded a clear screen recording (or combination of screen + physical demo) showing the app's full functionality. Uploaded the video to an accessible URL (YouTube unlisted, Dropbox, etc.) and included the link in the App Review notes. The video showed: device pairing, feature usage, and all key user flows.",
53
- "outcome": "approved-after-fix",
54
- "keywords": ["video-demo", "hardware-dependent", "bluetooth", "ar", "iot", "demonstration"],
55
- "behavioralSignals": ["app requires external hardware", "Bluetooth pairing needed", "AR features untestable", "reviewer can't replicate conditions"],
56
- "year": 2024
57
- },
58
- {
59
- "id": "full-disk-access-permission-display-bug",
60
- "guidelineNumber": "2.1",
61
- "guidelineName": "App Completeness",
62
- "category": "performance",
63
- "rejectionReason": "Your macOS app's Full Disk Access permission is not displaying correctly in System Preferences.",
64
- "whatDeveloperDid": "Built a macOS app that required Full Disk Access for backup or file management functionality. Due to a macOS bug, the app's entry in System Preferences > Privacy & Security > Full Disk Access was not showing the correct app name or icon, making it impossible for the reviewer to grant the permission.",
65
- "whatAppleSaid": "Guideline 2.1 - Performance - App Completeness: We were unable to grant Full Disk Access to your app. The app does not appear correctly in the Full Disk Access section of System Preferences. Without this permission, we cannot test the app's core functionality.",
66
- "fix": "Ensured the app is properly code-signed and notarized. Added the correct bundle identifier and app name in Info.plist. For the macOS bug: provided detailed instructions in the review notes on how to manually add the app to Full Disk Access via the '+' button. Filed a Feedback with Apple about the System Preferences display issue.",
67
- "outcome": "approved-after-fix",
68
- "keywords": ["full-disk-access", "macos", "system-preferences", "permission", "display-bug"],
69
- "behavioralSignals": ["app not showing in Full Disk Access", "permission display issue", "macOS System Preferences bug", "can't grant FDA permission"],
70
- "year": 2023
71
- },
72
- {
73
- "id": "app-approved-removed-re-rejected-doppel",
74
- "guidelineNumber": "3.2",
75
- "guidelineName": "Other Business Model Issues",
76
- "category": "business",
77
- "rejectionReason": "Your previously approved app has been removed from the App Store and re-rejected upon resubmission.",
78
- "whatDeveloperDid": "Doppel AI was initially approved and published on the App Store. It was later removed by Apple for guideline concerns (potentially related to deepfake/AI-generated content of real people). When the developer attempted to resubmit with modifications, the app was rejected again with additional scrutiny.",
79
- "whatAppleSaid": "Your app was previously removed from the App Store for guideline violations. Upon re-review, we have determined that the app still does not comply with the App Store Review Guidelines. Your app creates AI-generated likenesses of real people, which raises concerns under Guidelines 1.1 and 5.1 regarding user safety and privacy.",
80
- "fix": "The developer had to fundamentally rethink the app's approach to AI-generated content. Added consent verification for any real person whose likeness is generated, removed the ability to create content of public figures without authorization, implemented content safety filters, and added clear labeling of all AI-generated content.",
81
- "outcome": "approved-after-fix",
82
- "keywords": ["app-removal", "re-rejection", "deepfake", "ai-content", "removed-from-store", "policy-change"],
83
- "behavioralSignals": ["previously removed app", "AI-generated likenesses", "deepfake capabilities", "re-review after removal"],
84
- "year": 2024
85
- },
86
- {
87
- "id": "deep-link-redirect-broken-ios18",
88
- "guidelineNumber": "2.1",
89
- "guidelineName": "App Completeness",
90
- "category": "performance",
91
- "rejectionReason": "Your app's deep link handling is broken, causing incorrect navigation.",
92
- "whatDeveloperDid": "The app's Universal Links and deep link handling broke after an iOS 18 update. Deep links from emails and web pages either opened Safari instead of the app, opened the app to the wrong screen, or caused a redirect loop between the app and Safari.",
93
- "whatAppleSaid": "Guideline 2.1 - Performance - App Completeness: We found that deep links to your app do not work correctly. Tapping a link that should open your app instead opens Safari, or opens the app to an incorrect screen. Please ensure your app's deep link handling works correctly on iOS 18.",
94
- "fix": "Updated the Apple App Site Association (AASA) file to use the new format compatible with iOS 18. Verified the AASA file is served with the correct Content-Type (application/json). Updated the app's URL handling code to use the new UIScene-based URL handling. Tested all deep link scenarios on iOS 18 devices.",
95
- "outcome": "approved-after-fix",
96
- "keywords": ["deep-link", "universal-links", "ios18", "aasa", "url-handling", "redirect"],
97
- "behavioralSignals": ["deep links open Safari instead of app", "wrong screen on deep link", "redirect loop between app and Safari", "Universal Links broken after update"],
98
- "year": 2024
99
- },
100
- {
101
- "id": "crypto-wallet-regulatory-rejection",
102
- "guidelineNumber": "3.1.5",
103
- "guidelineName": "Cryptocurrencies",
104
- "category": "business",
105
- "rejectionReason": "Your cryptocurrency wallet app does not comply with regulatory requirements for the regions where it operates.",
106
- "whatDeveloperDid": "Submitted a cryptocurrency wallet app that allowed users to buy, sell, and trade cryptocurrencies but did not have the required financial services licenses or registrations for the jurisdictions where it planned to operate.",
107
- "whatAppleSaid": "Guideline 3.1.5(b) - Business - Cryptocurrencies: Your app facilitates cryptocurrency transactions but does not appear to comply with applicable legal requirements. Cryptocurrency exchanges and wallets must be offered by enrolled developers that are licensed or registered to provide such services in the jurisdictions where the app is available.",
108
- "fix": "Restricted the app's availability to jurisdictions where the company holds valid licenses. Provided Apple with documentation of regulatory compliance (money transmitter licenses, FinCEN registration, etc.). Added required legal disclosures, terms of service, and risk warnings within the app.",
109
- "outcome": "approved-after-fix",
110
- "keywords": ["cryptocurrency", "wallet", "regulatory", "financial-services", "licensing", "compliance"],
111
- "behavioralSignals": ["crypto trading without licenses", "financial services without registration", "missing regulatory compliance", "cryptocurrency exchange app"],
112
- "year": 2023
113
- },
114
- {
115
- "id": "app-size-exceeding-4gb-limit",
116
- "guidelineNumber": "2.3",
117
- "guidelineName": "Accurate Metadata",
118
- "category": "performance",
119
- "rejectionReason": "Your app bundle exceeds the maximum allowed size.",
120
- "whatDeveloperDid": "Submitted an app whose total bundle size (including all architectures and resources) exceeded 4GB. The app included large uncompressed assets, multiple video files, and unoptimized images that pushed the binary size over Apple's limit.",
121
- "whatAppleSaid": "ERROR ITMS-90381: The app's total uncompressed size exceeds the maximum allowed size of 4GB. Your app bundle (including all architectures) is approximately 4.7GB. Please reduce the size of your app.",
122
- "fix": "Used On-Demand Resources (ODR) to host large assets on Apple's servers and download them only when needed. Compressed image and video assets. Used Asset Catalogs with app slicing to deliver only the assets needed for each device. Moved large content to a post-install download with user consent.",
123
- "outcome": "approved-after-fix",
124
- "keywords": ["app-size", "binary-size", "4gb-limit", "on-demand-resources", "asset-optimization"],
125
- "behavioralSignals": ["app exceeds 4GB", "large uncompressed assets", "ITMS-90381 error", "oversized binary"],
126
- "year": 2023
127
- },
128
- {
129
- "id": "forced-push-notification-acceptance",
130
- "guidelineNumber": "5.1.1",
131
- "guidelineName": "Data Collection and Storage",
132
- "category": "legal",
133
- "rejectionReason": "Your app requires users to accept push notifications to use the app.",
134
- "whatDeveloperDid": "Displayed the push notification permission dialog on launch and, if the user denied it, showed a blocking screen that prevented access to the app until notifications were enabled. The app essentially held core functionality hostage to push notification consent.",
135
- "whatAppleSaid": "Guideline 5.1.1 - Legal - Privacy: Your app requires users to grant push notification permission to access the app's functionality. Users must be able to use your app's core features without being required to accept push notifications. Permission requests must be optional and the app must remain functional if the user declines.",
136
- "fix": "Made push notification permission optional. Removed the blocking screen. The app now functions fully without push notifications enabled. Added a gentle, non-blocking prompt explaining the benefits of notifications at a contextually appropriate moment (e.g., after booking an appointment: 'Would you like to receive reminders?').",
137
- "outcome": "approved-after-fix",
138
- "keywords": ["push-notifications", "forced-permission", "notification-required", "blocking-screen", "permission-gate"],
139
- "behavioralSignals": ["app blocked without notification permission", "forced notification acceptance", "can't use app without push enabled", "blocking screen on permission denial"],
140
- "year": 2023
141
- },
142
- {
143
- "id": "always-location-when-while-using-sufficient",
144
- "guidelineNumber": "5.1.2",
145
- "guidelineName": "Data Use and Sharing",
146
- "category": "legal",
147
- "rejectionReason": "Your app requests 'Always' location permission when 'While Using' would be sufficient.",
148
- "whatDeveloperDid": "Requested 'Always' location permission (requestAlwaysAuthorization) for a restaurant finder app that only needed location while the user was actively browsing. Background location was not needed for any user-facing feature.",
149
- "whatAppleSaid": "Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing: Your app requests Always location authorization, but your app's use of location appears to only require 'While Using the App' authorization. Please request the minimum level of location access necessary for your app's functionality.",
150
- "fix": "Changed from requestAlwaysAuthorization() to requestWhenInUseAuthorization(). Updated NSLocationWhenInUseUsageDescription with a clear description. Removed NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationAlwaysUsageDescription from Info.plist since background location is not needed.",
151
- "outcome": "approved-after-fix",
152
- "keywords": ["location-permission", "always-location", "while-using", "privacy", "minimum-permission"],
153
- "behavioralSignals": ["Always location requested unnecessarily", "background location not justified", "excessive permission request", "location tracking beyond need"],
154
- "year": 2023
155
- },
156
- {
157
- "id": "ios13-always-location-behavior-change",
158
- "guidelineNumber": "5.1.2",
159
- "guidelineName": "Data Use and Sharing",
160
- "category": "legal",
161
- "rejectionReason": "Your app's location permission flow does not account for the iOS 13+ provisional 'Allow Once' behavior.",
162
- "whatDeveloperDid": "The app requested Always location permission, but starting with iOS 13, the system no longer shows 'Always Allow' as an option in the initial prompt. Instead, iOS shows 'Allow While Using App', 'Allow Once', and 'Don't Allow'. The 'Always' option only appears later as a separate system prompt if the app demonstrates legitimate background location usage.",
163
- "whatAppleSaid": "Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing: Your app's location permission handling does not properly adapt to iOS 13+ behavior. The app expects Always location authorization but the initial system prompt no longer offers this option. Please update your app to gracefully handle the provisional 'While Using' permission and request escalation to Always only when justified.",
164
- "fix": "Updated the permission flow to first request When In Use authorization, then request Always authorization as a separate step. Handled the CLAuthorizationStatus.authorizedWhenInUse state gracefully. The app now works with When In Use and only prompts for escalation to Always when the user triggers a feature that genuinely requires background location.",
165
- "outcome": "approved-after-fix",
166
- "keywords": ["location-permission", "ios13", "always-allow", "provisional", "authorization-change"],
167
- "behavioralSignals": ["app expects Always location immediately", "doesn't handle When In Use fallback", "permission flow broken on iOS 13+", "location authorization state not handled"],
168
- "year": 2020
169
- },
170
- {
171
- "id": "metadata-language-mismatch",
172
- "guidelineNumber": "2.3",
173
- "guidelineName": "Accurate Metadata",
174
- "category": "performance",
175
- "rejectionReason": "Your app's metadata language does not match the primary language of the app.",
176
- "whatDeveloperDid": "Submitted an app where the App Store metadata (title, subtitle, description, keywords) was in English, but the app's UI was entirely in Korean. Or vice versa: app was in English but metadata was submitted in another language's storefront.",
177
- "whatAppleSaid": "Guideline 2.3 - Performance - Accurate Metadata: Your app's App Store metadata language does not match the primary language of your app. The app description and title are in English, but the app's interface is in Korean. Please ensure your metadata language matches your app's primary language for each localization.",
178
- "fix": "Matched the App Store metadata language to the app's primary language for each localization. Added proper localized metadata for each language the app supports. Used App Store Connect's localization feature to provide language-specific metadata for each storefront.",
179
- "outcome": "approved-after-fix",
180
- "keywords": ["metadata", "localization", "language-mismatch", "app-store-connect", "localized-metadata"],
181
- "behavioralSignals": ["metadata in different language than app", "English description for non-English app", "language inconsistency", "storefront language mismatch"],
182
- "year": 2023
183
- },
184
- {
185
- "id": "release-notes-irrelevant-info",
186
- "guidelineNumber": "2.3",
187
- "guidelineName": "Accurate Metadata",
188
- "category": "performance",
189
- "rejectionReason": "Your app's release notes contain irrelevant or inappropriate content.",
190
- "whatDeveloperDid": "Used the release notes field for promotional messaging ('SALE: 50% off premium!'), internal development notes ('Fixed Bob's bug from Sprint 23'), social media links, or unrelated commentary instead of describing what changed in the update.",
191
- "whatAppleSaid": "Guideline 2.3 - Performance - Accurate Metadata: Your app's release notes contain content that is not relevant to the app update. Release notes should describe what is new or changed in the current version. Please update your release notes to accurately describe the changes in this update.",
192
- "fix": "Rewrote release notes to focus on user-facing changes: new features, bug fixes, and improvements. Removed promotional content, internal references, and unrelated commentary. Example: 'What's New: - Fixed an issue where photos wouldn't save correctly. - Improved loading speed for the feed. - Added dark mode support.'",
193
- "outcome": "approved-after-fix",
194
- "keywords": ["release-notes", "metadata", "what-is-new", "promotional-content", "update-description"],
195
- "behavioralSignals": ["promotional text in release notes", "internal dev notes visible", "irrelevant content in What's New", "non-descriptive release notes"],
196
- "year": 2023
197
- },
198
- {
199
- "id": "emoji-usage-inconsistent-enforcement",
200
- "guidelineNumber": "2.3",
201
- "guidelineName": "Accurate Metadata",
202
- "category": "performance",
203
- "rejectionReason": "Your app's metadata contains emoji characters which are not permitted in certain fields.",
204
- "whatDeveloperDid": "Used emoji characters in the app name, subtitle, or description in App Store Connect. While some apps have emojis in their metadata, Apple's enforcement is inconsistent - some apps get rejected while similar apps with emojis remain published.",
205
- "whatAppleSaid": "Guideline 2.3 - Performance - Accurate Metadata: Your app's name/subtitle includes emoji characters. App names and subtitles should use only standard text characters. Please remove emoji from your app name and subtitle. Note: emoji may be acceptable in the app description in some cases.",
206
- "fix": "Removed all emoji characters from the app name and subtitle fields. Emojis can sometimes be used in the longer description field, but it's safest to avoid them entirely. Used descriptive text instead of emoji to convey the app's purpose.",
207
- "outcome": "approved-after-fix",
208
- "keywords": ["emoji", "app-name", "metadata", "inconsistent-enforcement", "subtitle"],
209
- "behavioralSignals": ["emoji in app name", "emoji in subtitle", "special characters in metadata", "inconsistent rejection for emoji use"],
210
- "year": 2023
211
- }
212
- ]