A prompt library is useful when each prompt names inputs, boundaries and a check. Without recorded outputs, it is a set of exercises rather than evidence that a phrase reliably improves SwiftUI.
- 1Choose one behavior
- 2Supply project context
- 3Request bounded change
- 4Inspect result
Work through the example
Adapt the supplied prompts to a known scheme and one screen. Preserve failed attempts rather than deleting them from a success story.
Start with a disposable branch and synthetic data. Write the expected outcome before changing the implementation, then keep the first failing result. This prevents a later repair from quietly redefining the task. The procedure below is grounded in the repository reference; its examples must still be checked against your project and installed toolchain.
Implementation reference
The following focused section is adapted from the maintained project guide. It preserves the source’s examples and limitations.
Prompt Template
Use this exact template when turning a description into an executable prompt:
You are building a native iOS app from this user description:
"<USER_DESCRIPTION>"
Create a production-ready SwiftUI implementation with:
- iOS deployment target: iOS 17+ unless the user asks otherwise
- Architecture: MVVM with protocol-based dependencies
- State: @MainActor @Observable view models for UI-rendered state
- Navigation: typed routes and deep-link-ready structure
- Design: tokenized colors, spacing, typography, radius, shadows
- Accessibility: Dynamic Type, VoiceOver labels, 44pt targets, contrast checks
- Previews: every main state must render without network or disk
- Testing: unit-testable use cases and injected repositories
Derived product brief:
- Name:
- Audience:
- Problem:
- Primary user journey:
- Secondary flows:
- Data model:
- Offline behavior:
Derived visual direction:
- Personality:
- Color tokens:
- Typography:
- Component style:
- Motion:
Implement:
1. App entry point
2. Theme/design tokens
3. Models
4. Repository protocols and mock repositories
5. View models
6. Screens
7. Reusable components
8. Previews
9. Tests where practical
Do not:
- Use raw colors, spacing, or font sizes in views
- Create live dependencies inside view models
- Use @Observable without @MainActor for UI state
- Claim the app works without build/test/screenshot evidence
Acceptance and failure review
| Checkpoint | What to inspect | If it does not match |
|---|---|---|
| Choose one behavior | Confirm the input and environment | Preserve the failure and return to this step |
| Supply project context | Inspect the intermediate artifact | Preserve the failure and return to this step |
| Request bounded change | Run the focused check | Preserve the failure and return to this step |
| Inspect result | Record the observed result | Preserve the failure and return to this step |
Ask the agent to explain the smallest change that resolves the observed mismatch. Keep unrelated refactors out of the repair. A change that makes a warning disappear is not enough if the behavior or ownership contract has changed. Re-run the same acceptance check so the before and after results are comparable.
Twenty-five practice prompts
Use the request column as a starting sentence; supply the actual file and behavior. These are not labelled tested because this chapter does not contain 25 recorded model sessions.
| Topic | Request | Check |
|---|---|---|
| Empty library | Describe the first useful action | No items is distinct from failure |
| Empty search | Add a clear-query action | Stored data remains intact |
| Loading | Show progress without duplicate requests | One request per intended action |
| Error | Preserve useful data on failure | Retry has a defined effect |
| Add form | Reject blank titles | Whitespace-only input fails |
| Edit form | Support cancellation | Original data is unchanged |
| Deletion | Explain recovery behavior | Deletion affects only selected item |
| Persistence | Use an injected store | Relaunch preserves data |
| Search | Define matching rules | Case behavior is intentional |
| Navigation | Use stable route identity | Missing item has a fallback |
| Deep link | Validate input | Unknown route does not crash |
| Dark mode | Use semantic tokens | Text remains readable |
| High contrast | Use explicit assets | Variants resolve correctly |
| Dynamic Type | Allow content to grow | Long labels do not clip |
| VoiceOver label | Name the action meaningfully | Label describes the control |
| Focus | Preserve a sensible destination | Dismissal restores context |
| Cancellation | Stop obsolete work | Stale result cannot replace current data |
| Networking | Validate status before decoding | Error payload is not success |
| Previews | Inject deterministic fixtures | No production disk or network access |
| Unit test | Assert one domain transition | Test fails for a broken transition |
| UI test | Use stable identifiers | Wait for observable state |
| Screenshots | Name state and destination | Image matches requested state |
| Refactor | Preserve public behavior | Same acceptance suite passes |
| Review | Locate one finding | Supporting source is included |
| Completion | Separate executed from unverified | No unsupported success claim |
Evidence and limits
The prompts below are practice prompts, not 25 completed comparative runs.
This is an educational guide. Its presence in the series does not certify a completed client-specific lab. The series evidence record separates executed checks from exercises and blocked environments.
Inspect the source used in this lesson.
Related reading
- SwiftUI: review state transitions before polishing the screen
Make loading, empty, success and error states part of the implementation brief.
- Gemini CLI: connect once and review one iOS feature
Avoid duplicate connections and keep setup evidence separate from app evidence.
What to do next
Next: When a SwiftUI agent task fails: ten failure categories to distinguish