https://github.com/ParthJadhav/ios-marketing-capture
Automate Multi-Locale asset creation for your iOS app.
https://github.com/ParthJadhav/ios-marketing-capture
app-store claude-code codex ios localization marketing screenshots skills swiftui xcode
Last synced: 3 days ago
JSON representation
Automate Multi-Locale asset creation for your iOS app.
- Host: GitHub
- URL: https://github.com/ParthJadhav/ios-marketing-capture
- Owner: ParthJadhav
- License: mit
- Created: 2026-04-10T16:38:55.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-10T19:35:01.000Z (3 months ago)
- Last Synced: 2026-06-25T03:25:27.055Z (25 days ago)
- Topics: app-store, claude-code, codex, ios, localization, marketing, screenshots, skills, swiftui, xcode
- Language: Shell
- Homepage:
- Size: 22.5 KB
- Stars: 247
- Watchers: 0
- Forks: 14
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- claude-code-skills-zh - ParthJadhav/ios-marketing-capture
README
[](https://bloom.parthjadhav.com)
# iOS Marketing Capture
A skill for AI-powered coding agents (Claude Code, Cursor, Windsurf, etc.) that automates marketing screenshot capture for SwiftUI iOS apps. It builds an in-app capture system, seeds demo data, snapshots every screen and UI element, and loops across all your locales automatically.
#### Built for and used by Bloom - https://apps.apple.com/us/app/bloom-coffee-shelf-recipe/id6759914524
## What it does
- Adds a `#if DEBUG`-gated capture system to your app target — zero production footprint
- Seeds deterministic demo data so every screenshot looks populated and polished
- Navigates to each screen programmatically via a step-based coordinator
- Snapshots the full window including status bar, safe area, and presented sheets
- Renders isolated elements (cards, widgets, charts) via `ImageRenderer` at 3x with transparency
- Loops every locale automatically — one build, N relaunches with `-AppleLanguages`
- Works with any SwiftUI navigation pattern: `TabView`, `NavigationStack`, `NavigationSplitView`
## Install
### Using npx skills (recommended)
```bash
npx skills add ParthJadhav/ios-marketing-capture
```
This works with Claude Code, Cursor, Windsurf, OpenCode, Codex, and [40+ other agents](https://github.com/vercel-labs/skills#available-agents).
Install globally (available across all projects):
```bash
npx skills add ParthJadhav/ios-marketing-capture -g
```
Install for a specific agent:
```bash
npx skills add ParthJadhav/ios-marketing-capture -a claude-code
```
### Manual (git clone)
```bash
git clone https://github.com/ParthJadhav/ios-marketing-capture ~/.claude/skills/ios-marketing-capture
```
## Usage
Once installed, the skill triggers automatically when you ask your agent to:
- Capture marketing screenshots for my iOS app
- Generate locale screenshots across all languages
- Render my widgets as isolated PNGs
- Automate App Store screenshot capture
Or just tell the agent what you need:
```
> Capture marketing screenshots for my app across all locales
```
The agent will ask you about your screens, elements, locales, device, appearance, and seed data before writing any code.
## Example prompts
These are good starting prompts because they provide context while still leaving room for the skill to guide the process.
### Coffee app
```text
Capture marketing screenshots for my coffee tracking app.
I want Home, Shelf, Coffee Detail, Brew Timer, and Settings.
Also render coffee cards and all my widgets as isolated elements.
Capture across en, de, es, fr, ja.
```
### Habit tracker
```text
Generate locale screenshots for my habit tracker app.
I need the dashboard, habit detail, streak view, and settings.
Light mode only, iPhone 17 simulator.
All 5 locales in my Localizable.xcstrings.
```
### Finance app
```text
Capture marketing assets for my finance app.
I want the overview, transaction list, budget detail, and charts.
Render the spending chart and category cards as isolated elements.
English and German only.
```
### Fitness app with widgets
```text
Automate App Store screenshot capture for my workout app.
Capture the main dashboard, workout detail mid-session, and history.
Render all my WidgetKit widgets (small, medium, lock screen) as isolated PNGs.
```
## Better prompt tips
- List the exact screens you want captured by tab name or navigation path
- Mention any components you want rendered independently (cards, widgets, charts)
- Specify locales explicitly or say "all locales in my xcstrings"
- Say which simulator and iOS version you want
- Mention if any screen needs to be captured in a non-default state (e.g. timer mid-countdown)
- Say light only, dark only, or both
## How it works
### In-app capture mode, not XCUITest
The skill uses an in-app capture approach instead of XCUITest / Fastlane:
- **No test target surgery** — many projects have none, and adding one means fragile pbxproj edits
- **Direct access to everything** — ViewModels, SwiftData, `ImageRenderer`, `UIWindow.drawHierarchy`
- **Faster** — `xcodebuild build` once, then `simctl launch` per locale (no test-bundle overhead)
- **Element renders require it** — `ImageRenderer` on widget views must run inside the app process
### Step-based coordinator
Each screenshot is a self-contained `CaptureStep`:
```swift
struct CaptureStep {
let name: String // "01-home"
let navigate: @MainActor () -> Void // put the app in the right state
let settle: Duration // wait for animations
let cleanup: (@MainActor () -> Void)? // tear down before next step
}
```
The coordinator is a simple loop — no hardcoded screen sequences. The agent composes steps for your specific navigation architecture.
### Navigation patterns
The skill covers three navigation architectures:
| Pattern | How steps drive it |
|---------|-------------------|
| `TabView(selection:)` | `setTab(index)` |
| `NavigationStack` + router | `router.push(.route)` / `router.popToRoot()` |
| `NavigationSplitView` | Set sidebar + detail selection bindings |
### Element rendering
Isolated components are rendered via `ImageRenderer` at 3x scale with natural background inside rounded corners and transparency outside:
```swift
MarketingElementHarness.renderElement(
name: "card-morning-blend",
width: 380,
cornerRadius: 20,
background: theme.background
) {
CoffeeCard(coffee: coffee, theme: theme)
.padding(.horizontal, 16)
.padding(.vertical, 12)
}
```
Widget rendering handles the quirks of rendering WidgetKit views outside the widget process (missing `containerBackground`, missing padding, `ProgressView` rendering bugs).
## What gets generated
The skill guides the agent to create:
```
YourApp/
├── Debug/
│ └── MarketingCapture.swift # Capture system (DEBUG-only)
├── ContentView.swift # Modified — DEBUG hook for seed + coordinator
├── Views/.../TimerView.swift # Modified — primed state hooks (if needed)
scripts/
└── capture-marketing.sh # Build + install + per-locale loop
```
### Output layout
```
marketing/
en/
01-home.png
02-detail.png
03-settings.png
elements/
card-morning-blend.png
widget-pulse-small.png
chart-cupping.png
de/
...
es/
...
```
## Known gotchas
The skill documents 11 real bugs discovered during development. These are all baked into the skill's guidance so the agent avoids them automatically:
| # | Gotcha | What happens |
|---|--------|--------------|
| 1 | Live Activities persist across launches | Next locale crashes on stale SwiftData references |
| 2 | Re-seeding per locale | CloudKit sync churn causes crashes |
| 3 | VMs setup before seed | Hold stale empty snapshots |
| 4 | Setting trigger binding to nil | Doesn't dismiss fullScreenCover — wrong screenshot |
| 5 | NavigationPath can't be popped externally | Must capture clean stack before pushed detail |
| 6 | `membershipExceptions` is an INCLUSION list | Widget target membership goes backwards |
| 7 | `ImageRenderer` + `ProgressView` | Renders as prohibited symbol without explicit style |
| 8 | `.containerBackground` outside WidgetKit | No-op — widget renders have no background |
| 9 | iPhone 8 Plus gone on iOS 26 | Legacy 6.5" simulator unavailable |
| 10 | Locale launch argument format | Parens are mandatory: `(xx)` not `xx` |
| 11 | SwiftUI animations in ImageRenderer | Captures frame 0, not the animated state |
## Pairs well with
Use [app-store-screenshots](https://github.com/ParthJadhav/app-store-screenshots) as a post-processing step to composite the captured PNGs into Apple-style marketing pages with device mockups, headlines, and gradients.
## Requirements
- Xcode 16+ (synchronized folder groups support)
- iOS 17+ deployment target (for `ImageRenderer`, `@Observable`)
- A simulator runtime matching your target iOS version
- Python 3 (used by the shell script for JSON parsing)
## Contributing
Contributions are welcome, especially around:
- Support for additional navigation patterns
- New gotcha documentation from real projects
- Cross-agent compatibility improvements
- Clearer docs and onboarding
## License
MIT