ios-paywall-creator 1.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/LICENSE +21 -0
- package/QUICKSTART.md +185 -0
- package/README.md +233 -0
- package/SKILL.md +679 -0
- package/bin/install.js +203 -0
- package/bin/postinstall.js +40 -0
- package/examples/iap-credits-example.md +216 -0
- package/examples/subscription-app-example.md +168 -0
- package/package.json +50 -0
- package/references/paywall-ui-patterns.md +342 -0
- package/references/storekit-manager-template.md +385 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ios-paywall-creator
|
|
3
|
+
description: |
|
|
4
|
+
Create production-grade iOS paywalls with StoreKit 2 integration for subscriptions and in-app purchases.
|
|
5
|
+
Use this skill whenever the user mentions paywalls, monetization, subscriptions, StoreKit, IAP, in-app purchases,
|
|
6
|
+
RevenueCat alternatives, or wants to add payment features to their iOS app. This skill guides developers through
|
|
7
|
+
the complete process from App Store Connect setup to beautiful paywall UI implementation, even if they don't
|
|
8
|
+
explicitly ask for a "paywall" - trigger for any subscription or IAP-related requests.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# iOS Paywall Creator
|
|
12
|
+
|
|
13
|
+
This skill helps iOS developers create production-ready paywalls with native StoreKit 2 implementation. It provides a guided workflow from App Store Connect configuration to polished UI implementation.
|
|
14
|
+
|
|
15
|
+
## Workflow Overview
|
|
16
|
+
|
|
17
|
+
The skill follows a structured process:
|
|
18
|
+
|
|
19
|
+
1. **Discovery** - Understand the app's monetization needs
|
|
20
|
+
2. **Product Planning** - Define subscription tiers or IAP products
|
|
21
|
+
3. **App Store Connect Setup** - Guide through subscription/IAP creation
|
|
22
|
+
4. **Design Phase** - Gather inspiration and define the paywall aesthetic
|
|
23
|
+
5. **Implementation** - Generate production-ready Swift code
|
|
24
|
+
|
|
25
|
+
## Using Interactive Questions
|
|
26
|
+
|
|
27
|
+
Throughout this workflow, you'll use the `AskUserQuestion` tool to gather user preferences. This provides a native MCQ (multiple-choice question) interface that's much better than text-based questions.
|
|
28
|
+
|
|
29
|
+
**When you see instructions like this:**
|
|
30
|
+
```
|
|
31
|
+
question: "Which subscription durations do you want to offer?"
|
|
32
|
+
header: "Durations"
|
|
33
|
+
multiSelect: false
|
|
34
|
+
options:
|
|
35
|
+
- label: "All Three: Weekly, Monthly & Yearly (Recommended)"
|
|
36
|
+
description: "Maximum flexibility..."
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**You should call the AskUserQuestion tool like this:**
|
|
40
|
+
```
|
|
41
|
+
AskUserQuestion with:
|
|
42
|
+
- questions: [
|
|
43
|
+
{
|
|
44
|
+
question: "Which subscription durations do you want to offer?",
|
|
45
|
+
header: "Durations",
|
|
46
|
+
multiSelect: false,
|
|
47
|
+
options: [
|
|
48
|
+
{
|
|
49
|
+
label: "All Three: Weekly, Monthly & Yearly (Recommended)",
|
|
50
|
+
description: "Maximum flexibility - users choose based on commitment level..."
|
|
51
|
+
},
|
|
52
|
+
...
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This creates a clean, interactive interface where users can click their choice instead of typing responses. Always use this pattern when you see question blocks in the instructions below.
|
|
59
|
+
|
|
60
|
+
## Step 1: Discovery & Product Planning
|
|
61
|
+
|
|
62
|
+
Start by understanding what the user needs to monetize.
|
|
63
|
+
|
|
64
|
+
### Gather Core Information:
|
|
65
|
+
|
|
66
|
+
Use the `AskUserQuestion` tool to collect essential information:
|
|
67
|
+
|
|
68
|
+
1. **Product Type** - Use AskUserQuestion:
|
|
69
|
+
```
|
|
70
|
+
question: "What type of in-app products do you want to offer?"
|
|
71
|
+
header: "Product Type"
|
|
72
|
+
multiSelect: false
|
|
73
|
+
options:
|
|
74
|
+
- label: "Auto-renewing Subscriptions (Recommended)"
|
|
75
|
+
description: "Recurring revenue model - users get ongoing access and are charged weekly/monthly/yearly. Best for content apps, productivity tools, and services. Highest lifetime value."
|
|
76
|
+
- label: "Consumable IAP"
|
|
77
|
+
description: "One-time purchases that get used up - like credits, tokens, or coins. Users can buy repeatedly. Good for games or apps with consumable resources."
|
|
78
|
+
- label: "Non-consumable IAP"
|
|
79
|
+
description: "One-time purchases that unlock features forever - like 'Remove Ads' or 'Unlock Premium'. Users buy once and own forever."
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
2. **Paywall Location** - Use AskUserQuestion:
|
|
83
|
+
```
|
|
84
|
+
question: "Where should the paywall appear in your app?"
|
|
85
|
+
header: "Placement"
|
|
86
|
+
multiSelect: true
|
|
87
|
+
options:
|
|
88
|
+
- label: "First Launch (Recommended)"
|
|
89
|
+
description: "Show paywall on first app open as a soft introduction. Good for establishing value early without being pushy."
|
|
90
|
+
- label: "Hard Paywall / Feature Gate"
|
|
91
|
+
description: "Block access to specific features until user subscribes. Most effective for converting users who see clear value."
|
|
92
|
+
- label: "Settings / Upgrade Section"
|
|
93
|
+
description: "User-initiated from a settings menu or upgrade button. Low pressure, but requires users to discover it."
|
|
94
|
+
- label: "After Trial Period"
|
|
95
|
+
description: "Show paywall after users have used the app for a few days/launches. Captures users who've experienced value."
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
3. **Ask as plain text:** "What features are locked behind the paywall?"
|
|
99
|
+
Understanding this helps contextualize the value proposition in the UI.
|
|
100
|
+
|
|
101
|
+
## Step 2: Subscription/IAP Planning
|
|
102
|
+
|
|
103
|
+
Based on their product type choice, guide them through planning:
|
|
104
|
+
|
|
105
|
+
### For Auto-Renewing Subscriptions:
|
|
106
|
+
|
|
107
|
+
**Subscription Durations** - Use AskUserQuestion:
|
|
108
|
+
```
|
|
109
|
+
question: "Which subscription durations do you want to offer?"
|
|
110
|
+
header: "Durations"
|
|
111
|
+
multiSelect: false
|
|
112
|
+
options:
|
|
113
|
+
- label: "All Three: Weekly, Monthly & Yearly (Recommended)"
|
|
114
|
+
description: "Maximum flexibility - users choose based on commitment level. Weekly for trial, Monthly most popular, Yearly for highest LTV. Covers all user preferences."
|
|
115
|
+
- label: "Monthly & Yearly Only"
|
|
116
|
+
description: "Most common setup - balances simplicity with choice. Monthly for casual users, Yearly for committed users. Skip weekly to reduce options."
|
|
117
|
+
- label: "Monthly Only"
|
|
118
|
+
description: "Simplest option - one price point to manage. Good for starting out, but limits revenue optimization opportunities."
|
|
119
|
+
- label: "Custom Combination"
|
|
120
|
+
description: "Choose your own mix - like Weekly + Yearly or just Yearly. Tell me which durations you want."
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For each tier they've selected, they'll need to decide:
|
|
124
|
+
- **Display Name** (e.g., "Premium Weekly", "Pro Monthly")
|
|
125
|
+
- **Price** (you'll guide them through App Store Connect pricing)
|
|
126
|
+
- **Product ID** (e.g., `com.yourapp.premium.weekly`)
|
|
127
|
+
- **Duration** (7 days, 1 month, 1 year)
|
|
128
|
+
|
|
129
|
+
**Free Trials & Introductory Offers** - Use AskUserQuestion:
|
|
130
|
+
```
|
|
131
|
+
question: "Do you want to offer a free trial or introductory offer?"
|
|
132
|
+
header: "Trial Offer"
|
|
133
|
+
multiSelect: false
|
|
134
|
+
options:
|
|
135
|
+
- label: "Free Trial (Recommended)"
|
|
136
|
+
description: "Users get X days free before first charge (e.g., '7-day free trial', '3-day free trial'). Best for conversion - lets users experience value risk-free. Industry standard."
|
|
137
|
+
- label: "Introductory Price"
|
|
138
|
+
description: "Discounted price for first billing period (e.g., '$0.99 for first month, then $9.99'). Good alternative if you want some upfront revenue."
|
|
139
|
+
- label: "Pay Up Front Discount"
|
|
140
|
+
description: "Reduced price for multiple periods paid upfront (e.g., '3 months for $19.99, then $9.99/month'). Less common but good for cash flow."
|
|
141
|
+
- label: "No Trial or Offer"
|
|
142
|
+
description: "Standard pricing from day one. Use if your value is immediately clear or you have other onboarding strategies."
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**If they select a trial option**, follow up by asking:
|
|
146
|
+
- For **Free Trial**: "How long should the free trial be?" (Common: 3 days, 7 days, 14 days, 1 month)
|
|
147
|
+
- For **Introductory Price**: "What should the intro price be and for how long?" (e.g., "$0.99 for first month")
|
|
148
|
+
- For **Pay Up Front**: "What's the discounted price and duration?" (e.g., "$19.99 for 3 months")
|
|
149
|
+
|
|
150
|
+
**Important:** Trials apply to new subscribers only. Users who've already had a trial won't see the offer again.
|
|
151
|
+
|
|
152
|
+
**Multiple Subscription Tiers** - Use AskUserQuestion:
|
|
153
|
+
```
|
|
154
|
+
question: "Do you need multiple subscription tiers with different feature sets?"
|
|
155
|
+
header: "Tier Structure"
|
|
156
|
+
multiSelect: false
|
|
157
|
+
options:
|
|
158
|
+
- label: "Single Tier"
|
|
159
|
+
description: "One 'Premium' or 'Pro' subscription that unlocks everything. Simplest to manage and explain. Recommended for most apps."
|
|
160
|
+
- label: "Multiple Tiers (Basic/Premium/Ultimate)"
|
|
161
|
+
description: "Different tiers with different features (e.g., Basic gets X, Premium gets X+Y, Ultimate gets everything). More complex but can capture more user segments."
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
If they choose multiple tiers, ask them to describe what features each tier includes. Each tier needs a separate subscription group in App Store Connect.
|
|
165
|
+
|
|
166
|
+
### For Consumable IAP:
|
|
167
|
+
|
|
168
|
+
Ask about each consumable product:
|
|
169
|
+
- **What does it provide?** (e.g., "100 AI credits", "50 tokens")
|
|
170
|
+
- **Product ID** (e.g., `com.yourapp.tokens.100`)
|
|
171
|
+
- **Display Name**
|
|
172
|
+
- **Price tier**
|
|
173
|
+
|
|
174
|
+
### For Non-Consumable IAP:
|
|
175
|
+
|
|
176
|
+
Similar to consumables, but emphasize this is a one-time purchase that persists forever.
|
|
177
|
+
|
|
178
|
+
## Step 3: App Store Connect Configuration & ID Collection
|
|
179
|
+
|
|
180
|
+
This is a critical step where many developers get stuck. Provide clear, step-by-step guidance, then collect the actual IDs to use in code generation.
|
|
181
|
+
|
|
182
|
+
### For Subscriptions:
|
|
183
|
+
|
|
184
|
+
1. **Navigate to App Store Connect:**
|
|
185
|
+
- Go to [appstoreconnect.apple.com](https://appstoreconnect.apple.com)
|
|
186
|
+
- Select your app
|
|
187
|
+
- Go to "Features" → "Subscriptions" (formerly "In-App Purchases")
|
|
188
|
+
|
|
189
|
+
2. **Create Subscription Group:**
|
|
190
|
+
- Click "+" to create a new subscription group
|
|
191
|
+
- Give it a reference name (e.g., "Premium Access")
|
|
192
|
+
- **Important:** Save the Subscription Group ID - they'll need this in code
|
|
193
|
+
|
|
194
|
+
3. **Add Subscriptions to Group:**
|
|
195
|
+
For each tier (weekly/monthly/yearly):
|
|
196
|
+
|
|
197
|
+
a. Click "+" to add a subscription to the group
|
|
198
|
+
|
|
199
|
+
b. **Reference Name:** Internal name (e.g., "Premium Weekly")
|
|
200
|
+
|
|
201
|
+
c. **Product ID:** Reverse domain format
|
|
202
|
+
- Example: `com.yourcompany.appname.premium.weekly`
|
|
203
|
+
- Must be unique and cannot be changed later
|
|
204
|
+
- Use lowercase, no spaces
|
|
205
|
+
|
|
206
|
+
d. **Subscription Duration:**
|
|
207
|
+
- Weekly: 7 days
|
|
208
|
+
- Monthly: 1 month
|
|
209
|
+
- Yearly: 1 year
|
|
210
|
+
|
|
211
|
+
e. **Pricing:**
|
|
212
|
+
- Click "Add Pricing"
|
|
213
|
+
- Select "Automatic Pricing" (recommended) or set custom per territory
|
|
214
|
+
- Choose a price tier (e.g., $4.99/week, $9.99/month, $49.99/year)
|
|
215
|
+
|
|
216
|
+
f. **Localization:**
|
|
217
|
+
- Add display name and description for each language
|
|
218
|
+
- This is what users see in the App Store
|
|
219
|
+
|
|
220
|
+
g. **Subscription Prices (Introductory Offers):**
|
|
221
|
+
If the user wants a free trial or intro offer:
|
|
222
|
+
- Click "Add Introductory Offer" in the Subscription Prices section
|
|
223
|
+
- Choose offer type:
|
|
224
|
+
- **Free Trial**: Select duration (3 days, 7 days, 2 weeks, 1 month, etc.)
|
|
225
|
+
- **Pay As You Go**: Discounted price per billing period
|
|
226
|
+
- **Pay Up Front**: One-time discounted price for multiple periods
|
|
227
|
+
- Select duration (how long the offer lasts)
|
|
228
|
+
- Click "Create" and it will apply to all territories
|
|
229
|
+
- **Important**: Each subscription can only have ONE introductory offer
|
|
230
|
+
- Users are eligible once per subscription group (won't see offer again after canceling)
|
|
231
|
+
|
|
232
|
+
h. **App Store Information:**
|
|
233
|
+
- Upload subscription benefits screenshots if needed
|
|
234
|
+
- Add promotional text
|
|
235
|
+
- If using trials, mention it: "Start your 7-day free trial"
|
|
236
|
+
|
|
237
|
+
4. **Set Up Subscription Group Info:**
|
|
238
|
+
- Return to the subscription group level
|
|
239
|
+
- Add localized display name for the group
|
|
240
|
+
- This appears in Settings when users manage subscriptions
|
|
241
|
+
|
|
242
|
+
5. **Get Your Subscription Group ID:**
|
|
243
|
+
- In the subscription group overview, find the "Group ID"
|
|
244
|
+
- It's usually a numeric value like "21995608"
|
|
245
|
+
- **Copy this** - you'll use it in `StoreKitManager`
|
|
246
|
+
|
|
247
|
+
### For In-App Purchases (Consumables/Non-Consumables):
|
|
248
|
+
|
|
249
|
+
1. **Navigate to App Store Connect:**
|
|
250
|
+
- Go to your app → "Features" → "In-App Purchases"
|
|
251
|
+
|
|
252
|
+
2. **Create IAP:**
|
|
253
|
+
- Click "+" to create new in-app purchase
|
|
254
|
+
- Select type (Consumable or Non-Consumable)
|
|
255
|
+
|
|
256
|
+
3. **Configure:**
|
|
257
|
+
- **Reference Name:** Internal identifier
|
|
258
|
+
- **Product ID:** e.g., `com.yourapp.tokens.100`
|
|
259
|
+
- **Pricing:** Same process as subscriptions
|
|
260
|
+
- **Localization:** Display name and description
|
|
261
|
+
|
|
262
|
+
4. **Important:** For consumables that need backend verification (like credits), note that you'll need to track these server-side.
|
|
263
|
+
|
|
264
|
+
### StoreKit Configuration File (Optional but Recommended):
|
|
265
|
+
|
|
266
|
+
For testing in Xcode:
|
|
267
|
+
1. File → New → File → "StoreKit Configuration File"
|
|
268
|
+
2. Add your products manually for local testing
|
|
269
|
+
3. This lets you test purchases without App Store Connect
|
|
270
|
+
|
|
271
|
+
### Collect Product IDs (Critical for Code Generation)
|
|
272
|
+
|
|
273
|
+
After they've created their products in App Store Connect, **ask them to provide the actual IDs** so you can generate code that works immediately without placeholders.
|
|
274
|
+
|
|
275
|
+
**For Subscriptions, ask:**
|
|
276
|
+
|
|
277
|
+
"Now that you've created your subscriptions in App Store Connect, please provide:
|
|
278
|
+
|
|
279
|
+
1. **Subscription Group ID** (found in the subscription group overview - usually a numeric value like '21995608')
|
|
280
|
+
2. **Product IDs for each subscription** you created (e.g., 'com.yourapp.premium.weekly', 'com.yourapp.premium.monthly', 'com.yourapp.premium.yearly')
|
|
281
|
+
|
|
282
|
+
I'll use these exact IDs in the generated code so it's ready to use immediately."
|
|
283
|
+
|
|
284
|
+
**For IAP products, ask:**
|
|
285
|
+
|
|
286
|
+
"Please provide the **Product IDs** for each in-app purchase you created (e.g., 'com.yourapp.tokens.100', 'com.yourapp.unlock.premium')"
|
|
287
|
+
|
|
288
|
+
**Store these values** - you'll insert them directly into the generated code, replacing all placeholders. The user should not have to manually edit product IDs in the generated code.
|
|
289
|
+
|
|
290
|
+
## Step 4: Design & Inspiration Phase
|
|
291
|
+
|
|
292
|
+
Now that products are configured, design the paywall UI.
|
|
293
|
+
|
|
294
|
+
### Gather Inspiration:
|
|
295
|
+
|
|
296
|
+
Use AskUserQuestion to determine the design approach:
|
|
297
|
+
```
|
|
298
|
+
question: "How would you like to define the paywall design?"
|
|
299
|
+
header: "Design Input"
|
|
300
|
+
multiSelect: false
|
|
301
|
+
options:
|
|
302
|
+
- label: "I'll Provide a Screenshot (Recommended)"
|
|
303
|
+
description: "Upload an image of a paywall you like from another app. I'll analyze the colors, layout, typography, and recreate that style for your app."
|
|
304
|
+
- label: "Describe the Style I Want"
|
|
305
|
+
description: "Tell me your vision in words (e.g., 'modern and minimal', 'bold with gradients', 'warm and friendly'). I'll design based on your description."
|
|
306
|
+
- label: "Show Me Design Options"
|
|
307
|
+
description: "I'll generate 2-3 distinct theme options (Modern Minimalist, Warm & Friendly, Bold & Premium) and you can choose your favorite."
|
|
308
|
+
- label: "Copy a Specific App's Style"
|
|
309
|
+
description: "Name an app whose paywall you like (e.g., 'Duolingo', 'Notion', 'Calm') and I'll research and recreate that aesthetic."
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### If they provide an image:
|
|
313
|
+
|
|
314
|
+
1. Analyze the image carefully:
|
|
315
|
+
- Color scheme
|
|
316
|
+
- Layout structure (comparison table, card-based, minimal, feature-rich)
|
|
317
|
+
- Typography style
|
|
318
|
+
- Use of gradients, shadows, borders
|
|
319
|
+
- Button style
|
|
320
|
+
- Badge/highlight elements ("BEST VALUE", "SAVE 60%")
|
|
321
|
+
|
|
322
|
+
2. Ask clarifying questions:
|
|
323
|
+
- "I see this uses a bold orange accent - should we keep that or adjust?"
|
|
324
|
+
- "The layout shows a comparison table - do you want exactly that structure?"
|
|
325
|
+
- "Should we include badges like 'BEST VALUE' on certain tiers?"
|
|
326
|
+
|
|
327
|
+
### If they provide a description:
|
|
328
|
+
|
|
329
|
+
Extract the aesthetic direction and confirm:
|
|
330
|
+
- Tone (minimal, bold, playful, professional, luxurious)
|
|
331
|
+
- Colors mentioned
|
|
332
|
+
- Any specific UI elements
|
|
333
|
+
|
|
334
|
+
### If they want options:
|
|
335
|
+
|
|
336
|
+
Generate 2-3 distinct themes and present them to the user. Then use AskUserQuestion to let them choose:
|
|
337
|
+
|
|
338
|
+
**Example themes to generate:**
|
|
339
|
+
|
|
340
|
+
**Option 1: Modern Minimalist**
|
|
341
|
+
- Colors: Deep navy (#1a1f36) with electric blue accent (#00d4ff)
|
|
342
|
+
- Clean sans-serif fonts
|
|
343
|
+
- Generous white space
|
|
344
|
+
- Subtle shadows
|
|
345
|
+
- Card-based layout
|
|
346
|
+
|
|
347
|
+
**Option 2: Warm & Friendly**
|
|
348
|
+
- Colors: Soft peach (#ffe5d9) background with coral accent (#ff6b6b)
|
|
349
|
+
- Rounded corners everywhere
|
|
350
|
+
- Playful illustrations or icons
|
|
351
|
+
- Gentle gradients
|
|
352
|
+
|
|
353
|
+
**Option 3: Bold & Premium**
|
|
354
|
+
- Colors: Rich purple (#6366f1) to indigo gradient
|
|
355
|
+
- Gold accents (#fbbf24)
|
|
356
|
+
- Dramatic shadows
|
|
357
|
+
- Strong typography
|
|
358
|
+
- Luxury feel
|
|
359
|
+
|
|
360
|
+
After presenting the theme descriptions with color swatches, use AskUserQuestion:
|
|
361
|
+
```
|
|
362
|
+
question: "Which design theme do you prefer for your paywall?"
|
|
363
|
+
header: "Theme Choice"
|
|
364
|
+
multiSelect: false
|
|
365
|
+
options:
|
|
366
|
+
- label: "Modern Minimalist"
|
|
367
|
+
description: "Deep navy with electric blue accent. Clean, professional, generous spacing. Card-based layout with subtle shadows."
|
|
368
|
+
- label: "Warm & Friendly"
|
|
369
|
+
description: "Soft peach background with coral accent. Rounded corners, playful feel, gentle gradients. Approachable and inviting."
|
|
370
|
+
- label: "Bold & Premium"
|
|
371
|
+
description: "Purple-indigo gradient with gold accents. Dramatic shadows, strong typography. Conveys luxury and exclusivity."
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Confirm Before Coding:
|
|
375
|
+
|
|
376
|
+
After settling on a direction, show a brief description of what you'll build:
|
|
377
|
+
|
|
378
|
+
```
|
|
379
|
+
I'll create a paywall with:
|
|
380
|
+
- [Color scheme description]
|
|
381
|
+
- [Layout type: comparison table / card grid / minimal list]
|
|
382
|
+
- Subscription options: [Weekly $X, Monthly $Y, Yearly $Z]
|
|
383
|
+
- Features highlight section showing: [feature 1, feature 2, feature 3]
|
|
384
|
+
- [Any special elements like badges, animations]
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Wait for explicit approval** before generating code. Ask: "Does this sound right? Any changes to the design direction or features to highlight?"
|
|
388
|
+
|
|
389
|
+
## Step 5: Code Generation
|
|
390
|
+
|
|
391
|
+
Now generate production-ready Swift code using the reference templates.
|
|
392
|
+
|
|
393
|
+
### Pre-Generation Checklist
|
|
394
|
+
|
|
395
|
+
Before generating code, verify you have collected:
|
|
396
|
+
|
|
397
|
+
**For Subscriptions:**
|
|
398
|
+
- ✅ Subscription Group ID (numeric, e.g., "21995608")
|
|
399
|
+
- ✅ Product ID for each tier (e.g., "com.reelmark.premium.weekly")
|
|
400
|
+
- ✅ Which tiers they're using (weekly/monthly/yearly)
|
|
401
|
+
|
|
402
|
+
**For IAP:**
|
|
403
|
+
- ✅ Product ID for each IAP (e.g., "com.yourapp.tokens.100")
|
|
404
|
+
- ✅ Type (consumable or non-consumable)
|
|
405
|
+
|
|
406
|
+
**For UI:**
|
|
407
|
+
- ✅ Design direction confirmed
|
|
408
|
+
- ✅ Color scheme defined
|
|
409
|
+
- ✅ Features to highlight
|
|
410
|
+
- ✅ Terms of Service URL
|
|
411
|
+
- ✅ Privacy Policy URL
|
|
412
|
+
|
|
413
|
+
If any of these are missing, ask for them now before generating code.
|
|
414
|
+
|
|
415
|
+
### Core Components to Generate:
|
|
416
|
+
|
|
417
|
+
1. **StoreKitManager.swift** - Based on `references/storekit-manager-template.md`
|
|
418
|
+
- Transaction observer for real-time updates
|
|
419
|
+
- Product loading and purchase flow
|
|
420
|
+
- Subscription status checking
|
|
421
|
+
- Error handling
|
|
422
|
+
|
|
423
|
+
2. **PaywallView.swift** - Custom UI based on user's design inspiration
|
|
424
|
+
- SwiftUI view with their chosen aesthetic
|
|
425
|
+
- Product selection interface
|
|
426
|
+
- Feature comparison (if applicable)
|
|
427
|
+
- Terms of service and privacy policy links
|
|
428
|
+
|
|
429
|
+
3. **Integration Instructions** - How to add the paywall to their app
|
|
430
|
+
- Import statements
|
|
431
|
+
- App initialization code
|
|
432
|
+
- Where to present the paywall
|
|
433
|
+
|
|
434
|
+
### Code Generation Guidelines:
|
|
435
|
+
|
|
436
|
+
#### Use Reference Code Patterns:
|
|
437
|
+
|
|
438
|
+
Read `references/storekit-manager-template.md` and `references/paywall-view-template.md` for proven patterns. Don't reinvent the wheel - these templates have:
|
|
439
|
+
- Proper transaction verification
|
|
440
|
+
- Real-time subscription updates
|
|
441
|
+
- Correct async/await patterns
|
|
442
|
+
- Error handling
|
|
443
|
+
|
|
444
|
+
#### Customize Based on User's Setup:
|
|
445
|
+
|
|
446
|
+
**CRITICAL: Use the actual IDs they provided - do NOT use placeholders like "YOUR_GROUP_ID" or "com.yourapp.premium.weekly"**
|
|
447
|
+
|
|
448
|
+
Insert their real values:
|
|
449
|
+
- **Subscription Group ID**: Use the exact numeric ID they gave you (e.g., "21995608")
|
|
450
|
+
- **Product IDs**: Use their exact product IDs for each tier (e.g., "com.reelmark.premium.weekly")
|
|
451
|
+
- **Variable names**: Keep descriptive (e.g., `weeklySubscriptionID`, `monthlySubscriptionID`)
|
|
452
|
+
- Adapt `isProUser` logic based on their tier structure
|
|
453
|
+
- For IAP: include the consumable/non-consumable product IDs in the `Product.products(for:)` array
|
|
454
|
+
|
|
455
|
+
The generated code should work immediately when they copy it into their project - no manual ID replacement needed.
|
|
456
|
+
|
|
457
|
+
#### UI Customization:
|
|
458
|
+
|
|
459
|
+
Follow the design inspiration closely:
|
|
460
|
+
- Apply their color scheme using SwiftUI's `.foregroundStyle()` and `Color()`
|
|
461
|
+
- Match layout structure (cards, table, list)
|
|
462
|
+
- Include any special elements (badges, gradients, animations)
|
|
463
|
+
- Implement their typography preferences
|
|
464
|
+
|
|
465
|
+
**If they configured free trials or intro offers:**
|
|
466
|
+
- Display trial information prominently using StoreKit's built-in properties
|
|
467
|
+
- Use `product.subscription?.introductoryOffer` to check for offers
|
|
468
|
+
- Show trial duration: "7-day free trial", "Try free for 7 days"
|
|
469
|
+
- Include "then $9.99/month" to show price after trial
|
|
470
|
+
- Use the Product extension methods in the reference for `introOfferDescription`
|
|
471
|
+
- Consider highlighting trial offers with badges or special styling
|
|
472
|
+
- Make it clear in the button text if it's free trial or not.
|
|
473
|
+
|
|
474
|
+
#### Required Legal Elements:
|
|
475
|
+
|
|
476
|
+
Always include:
|
|
477
|
+
- Link to Terms of Service
|
|
478
|
+
- Link to Privacy Policy
|
|
479
|
+
- Text: "Subscriptions automatically renew unless cancelled"
|
|
480
|
+
- For Apple's standard EULA: `https://www.apple.com/legal/internet-services/itunes/dev/stdeula/`
|
|
481
|
+
- "Restore Purchases" button
|
|
482
|
+
|
|
483
|
+
Ask the user for their Terms and Privacy Policy URLs, or help them understand they need these.
|
|
484
|
+
|
|
485
|
+
#### Best Practices to Include:
|
|
486
|
+
|
|
487
|
+
- Use `@Observable` macro for StoreKitManager (iOS 17+) or `ObservableObject` for older versions
|
|
488
|
+
- Load products on initialization
|
|
489
|
+
- Auto-select a recommended plan (usually monthly)
|
|
490
|
+
- Show loading states
|
|
491
|
+
- Handle errors gracefully with user-friendly messages
|
|
492
|
+
- Include "Manage Subscription" button for existing subscribers
|
|
493
|
+
- Add intro offer support if they plan to use it
|
|
494
|
+
|
|
495
|
+
### Output Format:
|
|
496
|
+
|
|
497
|
+
Present the code as:
|
|
498
|
+
|
|
499
|
+
1. **A complete markdown document** with separate code blocks for each file
|
|
500
|
+
2. Each file clearly labeled with `// MARK: - Filename`
|
|
501
|
+
3. Include inline comments explaining key sections
|
|
502
|
+
4. Provide a "Quick Start" section showing how to integrate
|
|
503
|
+
|
|
504
|
+
Example structure:
|
|
505
|
+
|
|
506
|
+
```markdown
|
|
507
|
+
# Your iOS Paywall Implementation
|
|
508
|
+
|
|
509
|
+
✅ **All product IDs have been configured with your actual values from App Store Connect**
|
|
510
|
+
|
|
511
|
+
## 1. StoreKitManager.swift
|
|
512
|
+
|
|
513
|
+
Create this file in your project. All product IDs are already configured:
|
|
514
|
+
|
|
515
|
+
[Full code block with ACTUAL IDs]
|
|
516
|
+
|
|
517
|
+
## 2. PaywallView.swift
|
|
518
|
+
|
|
519
|
+
Create this file in your project:
|
|
520
|
+
|
|
521
|
+
[Full code block with user's design]
|
|
522
|
+
|
|
523
|
+
## 3. Integration
|
|
524
|
+
|
|
525
|
+
In your App struct or main view:
|
|
526
|
+
|
|
527
|
+
[Integration code]
|
|
528
|
+
|
|
529
|
+
## 4. Required Assets
|
|
530
|
+
|
|
531
|
+
- Add a paywall header image (if applicable): `PaywallImage` in Assets.xcassets
|
|
532
|
+
- Your product IDs are already in the code - no manual configuration needed!
|
|
533
|
+
|
|
534
|
+
## 5. Testing
|
|
535
|
+
|
|
536
|
+
[Testing instructions]
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Important**: At the top of the generated code, include a summary showing which IDs were used, so the user can verify they're correct at a glance.
|
|
540
|
+
|
|
541
|
+
## Step 6: Integration Guidance
|
|
542
|
+
|
|
543
|
+
After generating code, provide clear instructions on:
|
|
544
|
+
|
|
545
|
+
### Where to Show the Paywall:
|
|
546
|
+
|
|
547
|
+
Based on their earlier answers about where paywalls should appear:
|
|
548
|
+
|
|
549
|
+
**First Launch:**
|
|
550
|
+
```swift
|
|
551
|
+
.onAppear {
|
|
552
|
+
if !UserDefaults.standard.bool(forKey: "hasSeenPaywall") {
|
|
553
|
+
showPaywall = true
|
|
554
|
+
UserDefaults.standard.set(true, forKey: "hasSeenPaywall")
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
**Hard Paywall (Feature Gate):**
|
|
560
|
+
```swift
|
|
561
|
+
if !storeManager.isProUser {
|
|
562
|
+
PaywallView()
|
|
563
|
+
} else {
|
|
564
|
+
PremiumFeatureView()
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Settings/Upgrade Button:**
|
|
569
|
+
```swift
|
|
570
|
+
Button("Upgrade to Premium") {
|
|
571
|
+
showPaywall = true
|
|
572
|
+
}
|
|
573
|
+
.sheet(isPresented: $showPaywall) {
|
|
574
|
+
PaywallView()
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Initialize StoreKit:
|
|
579
|
+
|
|
580
|
+
In the App struct:
|
|
581
|
+
```swift
|
|
582
|
+
@main
|
|
583
|
+
struct YourApp: App {
|
|
584
|
+
init() {
|
|
585
|
+
StoreKitManager.shared.configure()
|
|
586
|
+
}
|
|
587
|
+
// ...
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
### Testing Checklist:
|
|
592
|
+
|
|
593
|
+
Provide a testing checklist:
|
|
594
|
+
- [ ] Products load correctly
|
|
595
|
+
- [ ] Can complete purchase flow
|
|
596
|
+
- [ ] Subscription status updates in real-time
|
|
597
|
+
- [ ] Restore purchases works
|
|
598
|
+
- [ ] UI looks correct on different screen sizes
|
|
599
|
+
- [ ] Terms and Privacy links work
|
|
600
|
+
- [ ] Error states display properly
|
|
601
|
+
|
|
602
|
+
## Design Best Practices
|
|
603
|
+
|
|
604
|
+
When creating the UI, follow these principles to avoid generic "AI slop" aesthetics:
|
|
605
|
+
|
|
606
|
+
### Typography
|
|
607
|
+
- Choose distinctive fonts that match the app's personality
|
|
608
|
+
- Avoid overused options (SF Pro is fine but consider custom fonts)
|
|
609
|
+
- Create hierarchy with size and weight
|
|
610
|
+
- Consider system font with design variation (`.rounded`, `.serif`)
|
|
611
|
+
|
|
612
|
+
### Color & Theme
|
|
613
|
+
- Commit to a cohesive palette
|
|
614
|
+
- Use the user's brand colors if they mention them
|
|
615
|
+
- Dominant color with sharp accents > evenly distributed pastels
|
|
616
|
+
- Support both light and dark mode (use `.primary`, `.secondary` for adaptive colors)
|
|
617
|
+
|
|
618
|
+
### Layout
|
|
619
|
+
- Don't be afraid of asymmetry
|
|
620
|
+
- Use generous spacing or controlled density (not in between)
|
|
621
|
+
- Consider scroll effects or animations for delight
|
|
622
|
+
- Make the best value option stand out visually
|
|
623
|
+
|
|
624
|
+
### Visual Details
|
|
625
|
+
- Add depth with shadows (`.shadow()`)
|
|
626
|
+
- Use gradients thoughtfully (`.fill(LinearGradient(...))`)
|
|
627
|
+
- Rounded corners for friendliness (`.cornerRadius()`)
|
|
628
|
+
- Highlight badges for "SAVE 60%" or "BEST VALUE"
|
|
629
|
+
- Consider subtle animations on appear
|
|
630
|
+
|
|
631
|
+
### What to Avoid
|
|
632
|
+
- Generic purple gradients on white backgrounds
|
|
633
|
+
- Cookie-cutter comparison tables (add personality)
|
|
634
|
+
- Cluttered information (prioritize clarity)
|
|
635
|
+
- Tiny legal text (make it readable)
|
|
636
|
+
|
|
637
|
+
## Reference Code
|
|
638
|
+
|
|
639
|
+
All reference implementations are available in:
|
|
640
|
+
- `references/storekit-manager-template.md` - Complete StoreKit 2 manager
|
|
641
|
+
- `references/paywall-view-template.md` - Customizable paywall UI examples
|
|
642
|
+
- `references/integration-patterns.md` - Common integration scenarios
|
|
643
|
+
|
|
644
|
+
Read these before generating code to ensure you're following proven patterns.
|
|
645
|
+
|
|
646
|
+
## Common Issues & Solutions
|
|
647
|
+
|
|
648
|
+
### "Products not loading"
|
|
649
|
+
- Check product IDs match exactly (case-sensitive)
|
|
650
|
+
- Ensure subscription group exists in App Store Connect
|
|
651
|
+
- Verify app's Bundle ID matches
|
|
652
|
+
- Check "Cleared for Sale" is enabled
|
|
653
|
+
- Try `try await AppStore.sync()` to refresh
|
|
654
|
+
|
|
655
|
+
### "Purchase completes but status doesn't update"
|
|
656
|
+
- Ensure `checkPurchasedProducts()` is called after purchase
|
|
657
|
+
- Verify transaction observer is initialized
|
|
658
|
+
- Check `Transaction.currentEntitlements` logic
|
|
659
|
+
|
|
660
|
+
### "UI looks wrong on smaller devices"
|
|
661
|
+
- Use `GeometryReader` for adaptive sizing
|
|
662
|
+
- Test on iPhone SE (smallest screen)
|
|
663
|
+
- Use `.minimumScaleFactor()` for text that must fit
|
|
664
|
+
|
|
665
|
+
## Final Deliverable
|
|
666
|
+
|
|
667
|
+
The complete implementation package should include:
|
|
668
|
+
|
|
669
|
+
1. ✅ `StoreKitManager.swift` - Fully configured with user's product IDs
|
|
670
|
+
2. ✅ `PaywallView.swift` - Custom UI matching their design inspiration
|
|
671
|
+
3. ✅ Integration instructions for their specific use case
|
|
672
|
+
4. ✅ Testing checklist
|
|
673
|
+
5. ✅ Links to required documentation
|
|
674
|
+
|
|
675
|
+
Remind the user:
|
|
676
|
+
- They need to submit their app with working IAP to App Store Review
|
|
677
|
+
- Test thoroughly in sandbox environment before release
|
|
678
|
+
- Consider offering a free trial (configured in App Store Connect)
|
|
679
|
+
- Monitor subscription metrics in App Store Connect
|