
Generating Demo Assets for an iOS App With AI: A Home Redesign App Case Study
The Project
Generating demo assets for an iOS app is the chore that quietly stalls development: you can't exercise a photo-driven feature without photos, and hand-sourcing dozens of licensed, on-spec images burns hours. This case study walks through generating 29 of them with AI and loading them straight into the iOS Simulator's Photos library.
The app is Roomix, an iOS home-redesign tool: photograph a room, pick a style, and it renders a reimagined space via ModelRunner's inference queue. The gap was that it shipped with no demo assets — no sample "before" photos to exercise the redesign flow, no interior/exterior product references, and no exterior scenes for the landscape feature. Every Simulator test session began with "go find a photo yourself," a friction point on every development and demo iteration.
The Problem: 29 Images, Zero Starting Points
To make the app testable and demo-ready, we needed four categories of images placed directly into the Xcode asset catalog (Assets.xcassets) so the iOS Simulator could pick them up automatically — and, critically, available in the Simulator's Photos library so they appear when a developer taps the photo picker inside the app:
| Category | Count | Purpose |
|---|---|---|
| Interior room "before" photos | 10 | Source photos users would redesign (living rooms, kitchens, bedrooms, etc.) |
| Interior product images | 10 | Product catalog items: sofas, tables, lighting, rugs, etc. |
| Exterior/garden product images | 4 | Outdoor furniture, planters, BBQ grills |
| Exterior scene "before" photos | 5 | Garden, balcony, patio, rooftop scenes for landscape redesign |
Hand-picking 29 royalty-free, high-quality photos from stock libraries would have taken hours of searching, licensing, and resizing. Generating them with AI from precise text prompts was the obvious alternative — but only if the generation API was easy enough to wire into an automated pipeline.

Why ModelRunner for Bulk AI Asset Generation
A few things made ModelRunner the right choice here:
1. It's already in the stack. Roomix already calls ModelRunner's queue API to submit interior redesign jobs. The same API key, the same request/poll pattern. There was no new service to sign up for, no new authentication to configure.
2. The MCP integration made automation trivial. ModelRunner exposes an MCP (Model Context Protocol) server, which means Claude Code — the AI coding assistant driving this session — could call mcp__modelrunner__run_model and mcp__modelrunner__wait_for_request as native tool calls, no shell scripting or REST client code required. The entire generation pipeline lived inside a Claude Code workflow.
3. Model selection was straightforward. A single call to list_models with category: "text-to-image" surfaced the full catalog. We chose Qwen-Image (qwen/qwen-image) for its strong photorealism, reliable prompt adherence for interior/product scenes, and per-megapixel pricing that keeps bulk generation affordable.
4. The async request pattern fits batch workloads perfectly. ModelRunner's run_model returns a requestId immediately; wait_for_request polls until completion. That pattern is trivially parallelizable — we submitted all 29 requests concurrently and let them resolve in parallel rather than waiting on each one serially.
How It Was Done: A Claude Code Generation Pipeline
The entire pipeline was orchestrated by a Claude Code Workflow — a deterministic multi-agent script that fans work out across parallel subagents.
The pipeline (per image)
Prompt → run_model (qwen/qwen-image) → requestId
→ wait_for_request → image URL
→ curl -L -o <path> → .jpg on disk
→ write Contents.json → valid .imageset bundle
Each of the 29 images went through this pipeline independently. The workflow's pipeline() primitive chained the three stages without a synchronization barrier — image A could be downloading while image B was still generating, maximizing throughput.
Folder structure written into xcassets
Assets.xcassets/
├── SampleRooms/ ← 10 interior room photos
│ ├── room-living-modern.imageset/
│ ├── room-bedroom-master.imageset/
│ └── ...
├── SampleProducts/
│ ├── Interior/ ← 10 interior product images
│ │ ├── product-sectional-sofa.imageset/
│ │ └── ...
│ └── Exterior/ ← 4 garden/balcony products
│ ├── product-outdoor-sofa.imageset/
│ └── ...
└── Exterior/ ← 5 exterior scene photos
├── exterior-garden-plain.imageset/
└── ...
Each .imageset folder contains the generated .jpg and a valid Contents.json that Xcode's asset catalog compiler understands. The images are immediately addressable in SwiftUI with Image("SampleRooms/room-living-modern").

Pushing the images into the iOS Simulator's photo library with xcrun simctl addmedia
Roomix's user flow starts at the photo picker (SwiftUI's PhotosPicker), which reads the simulator's Photos library — not Assets.xcassets. So images placed in the asset catalog still won't appear when a tester taps "choose a photo." Apple ships one command for exactly this:
xcrun simctl addmedia <SIMULATOR_UDID> /path/to/image.jpg
After generation we pushed all 29 .jpgs into the booted simulator in a single call:
IMAGES=$(find Assets.xcassets/SampleRooms \
Assets.xcassets/SampleProducts \
Assets.xcassets/Exterior \
-name "*.jpg" | sort)
echo "$IMAGES" | xargs xcrun simctl addmedia 3679DB58-5299-4CF3-B04A-72402311305A
From then on the in-app photo picker shows all 29 AI-generated images, ready to feed into the redesign flow. One caveat: the Photos library is per-simulator, so re-run addmedia against each new simulator's UDID — the xcassets copy stays the durable source of truth.

Reproducible asset generation, versioned in git
The simulator wiring above is one-time setup — the part that keeps paying off is generation, and that's the ModelRunner-shaped half of the problem. Every asset is just a text prompt against the qwen/qwen-image endpoint, so the prompts live in git next to the app code. Need a warmer palette, a different room style, or a localized set for another market? Re-run the same workflow and the whole library refreshes — no stock-photo relicensing, no re-shoot, no manual export.
Two ModelRunner properties make that practical at 29-image scale. First, the async queue: each run_model call returns a requestId immediately and wait_for_request resolves it independently, so the entire batch generates in parallel and finishes in under 10 minutes rather than serially. Second, per-megapixel pricing on qwen/qwen-image gives a flat, known cost for a full regeneration before you run it — the same API key and endpoint Roomix already uses for its core redesign feature. Demo assets stop being a one-off chore and become a repeatable build step you trigger whenever the app's look changes.
Prompt strategy
Prompts were tuned to the two distinct visual styles needed:
- Room/scene photos: "Photorealistic wide-angle photo of…, professional real estate interior photography" — anchored to the vocabulary of architectural photography to get natural lighting, correct perspective, and empty-room compositions.
- Product images: "Professional product photo of…, pure white background, studio lighting, centered composition" — studio-style isolation so the subject reads clearly as a catalog item.
Results: 29 Demo Images in Under 10 Minutes
- 29 images generated and placed in under 10 minutes of wall-clock time (parallel generation).
- Zero manual steps between "generate" and "usable in Xcode" — the workflow wrote the asset bundles directly.
- Consistent quality across all categories: photorealistic room scenes, clean white-background product shots, and credible exterior/garden vistas.
- The old placeholder assets (54 hand-picked style preview PNGs) were replaced entirely, reducing asset bundle size while adding coverage for new features.
Every image below was generated by qwen/qwen-image on ModelRunner in the same batch — tap any thumbnail to view the full-resolution output.
Rooms & scenes (10) — empty interiors for the redesign "before" state:
Product shots (14) — white-background catalog references for furniture and fixtures:
Exterior scenes (5) — outdoor spaces for the landscape redesign feature:
The Bigger Picture: ModelRunner as Workflow Infrastructure
This task illustrates a pattern that goes beyond asset generation: ModelRunner as infrastructure inside a developer workflow. Because ModelRunner exposes both a standard REST API and an MCP server, AI coding agents can call it as a first-class tool — not just as a backend for user-facing features, but as a capability the development process itself consumes.
For a product like Roomix that already depends on ModelRunner for its core AI feature, the jump from "ModelRunner powers our redesign renders" to "ModelRunner also populates our test asset library" required almost no additional integration work. The same pattern extended into generating the app's App Store marketing screenshots — and could keep going into onboarding illustrations or localized marketing visuals — all driven by prompts, versioned in git alongside code.
Roomix is built with SwiftUI and SwiftData, targeting iOS 17.0+. The asset generation workflow described here was authored and executed by Claude Code using the ModelRunner MCP server.
Appendix: Request IDs and output URLs (29 images)
Every image was generated via qwen/qwen-image on ModelRunner. The table below records each asset name and the durable output URL of its generated image.
