# Claude Code for Swift and iOS: a practical workflow

URL: https://agentvera.dev/en/blog/claude-code-for-swift/ · Published: 2026-11-01

Use Claude Code on Swift and iOS projects with a tight CLAUDE.md, plan-then-edit loop, xcodebuild tests, and safer parallel agents for iOS development.

**In short:**

- A tight CLAUDE.md with exact xcodebuild, swift test, and SwiftLint commands keeps the agent aligned with your project.
- Plan first, apply small diffs, run xcodebuild test or swift test, then review git diff before continuing.
- Watch Swift concurrency annotations, Xcode project file conflicts, simulator-only issues, and test isolation closely.

Claude Code can be a strong companion on Swift and iOS projects when it is wired into the same commands you already run in the terminal: xcodebuild, swift test, and swiftlint. When you run `claude` in the project folder, it reads a concise CLAUDE.md and works best in small plan-then-edit steps backed by real build and test output. This guide is a practical workflow for SwiftUI and UIKit apps, not a general AI overview; see [Claude Code](/en/agents/claude-code/) for the tool itself.

## Where Claude Code helps most on iOS

Swift and iOS development produces a lot of text-based signal: compiler diagnostics, SwiftLint output, XCTest failures, and package resolution logs. Claude Code can read that output, edit Swift files in place, and run the same commands from the project folder. That makes it useful for repetitive refactors like converting completion handlers to async/await, adding SwiftUI views from a feature spec, or writing XCTest cases. It also handles the boring cross-file work such as renaming a model property across feature folders, which usually requires many small edits in Xcode.

The agent stays most reliable when the project is code-based and has a clear structure. SwiftUI apps are easier than storyboard-heavy UIKit apps because the view hierarchy is in Swift files the agent can read. UIKit works too, but you should keep Interface Builder files out of the change surface unless the task explicitly requires them. Treat the agent as an engineer that has fast text manipulation but no visual simulator: it can reason about code and tests, but it cannot see the rendered UI.

## Give the agent a tight CLAUDE.md

Add a CLAUDE.md at the repository root. Keep it short and specific; the agent reads it before each task, so it should contain only commands and rules that prevent common iOS mistakes. A realistic file for a mixed SwiftUI/UIKit app with an SPM package might look like this:

```markdown
# CLAUDE.md for Acme iOS

## Build
- Run from repo root.
- App: xcodebuild -project Acme.xcodeproj -scheme Acme -destination 'platform=iOS Simulator,name=iPhone 16' build
- Tests: xcodebuild -project Acme.xcodeproj -scheme Acme -destination 'platform=iOS Simulator,name=iPhone 16' test
- Package: swift test

## Lint
- swiftlint lint --strict

## Conventions
- Deployment target iOS 17+, Swift 5.10+
- Folders: Acme/Features/<Feature>/Views, ViewModels, Models
- Tests mirror source paths under AcmeTests/Features/<Feature>
- Use SwiftUI for new screens; UIKit only when required.

## Rules
- Never edit Acme.xcodeproj/project.pbxproj manually unless asked; use Xcode or scripts.
- Prefer async/await over completion handlers.
- Mark non-final classes as final unless inheritance is intended.
- For SwiftUI, keep view models on @MainActor and use @Observable or ObservableObject.
- Run the relevant test command before claiming a task is done.
```

The most important rules are the ones that stop the agent from creating invalid Xcode project changes or ignoring concurrency rules. If you use SwiftLint, include the exact lint command and severity. If your package has platform requirements, note them so the agent does not add APIs above the deployment target, and keep the package manifest in sync yourself when needed.

## Plan, patch, test, review

A reliable loop is: plan first, edit in small diffs, run the relevant tests, review the diff, then either commit or hand back to the agent. Start in plan mode before non-trivial changes; it forces the agent to describe file changes and the test plan before touching code. The approach is covered in [Claude Code plan mode: plan first, then let it build](/en/blog/claude-code-plan-mode/). Then ask it to implement only the files from that plan. After the edit, run the test command from the project root, not just a visual inspection. Finally review `git diff` yourself or ask the agent to explain it.

Typical prompts:

- Plan the change for adding a retry button to `InvoiceListView` without modifying any other feature. List the files, view model changes, and the XCTest you will add, then stop.
- Implement the plan from the previous message. Keep the diff limited to the Invoices feature and do not edit `Acme.xcodeproj/project.pbxproj`.
- Run the Invoices test target with `xcodebuild test` and fix only the failing tests that this change introduced.
- Review the current diff for retain cycles, missing `@MainActor` annotations, and SwiftUI state management issues before I commit.
- Refactor `NetworkClient` to async/await while keeping its public API the same. Add unit tests using `URLProtocol` stubs.

## High-value tasks and iOS-specific pitfalls

The table below maps common iOS tasks to a prompt pattern and the failure mode to check.

| Task | Example prompt | Watch closely for |
|---|---|---|
| Add a SwiftUI screen | Add a Settings screen with NavigationStack in Features/Settings/Views using the existing Theme. | Missing environment objects, state that belongs in a model rather than @State, preview crashes. |
| Convert UIKit data loading | Refactor ProfileViewController’s data loading into a @MainActor view model using async/await. | Retain cycles, delegate callbacks from background queues, MainActor isolation errors. |
| Add unit tests | Add XCTest cases for CartViewModel using an in-memory repository; run only that test target. | Hidden singletons, shared state between tests, date/clock dependencies. |
| Fix Swift concurrency warnings | Fix strict concurrency warnings in Models/ without changing the public API. | Over-use of @unchecked Sendable instead of real isolation. |

Beyond the table, be careful with Xcode project files. If two agents or one agent and Xcode modify `project.pbxproj` at the same time, the merge is usually manual and painful. Keep the agent away from storyboards and xibs for code-only tasks, because diffing XML is noisy and it may introduce runtime-only errors that the compiler does not catch. On Swift concurrency, the agent often makes code compile by adding `@unchecked Sendable` when it should fix the isolation instead; review those annotations carefully.

## Run the real xcodebuild tests

For a Swift package, `swift test` is usually enough. For an iOS app target, use `xcodebuild -project Acme.xcodeproj -scheme Acme -destination 'platform=iOS Simulator,name=iPhone 16' test`. Run that exact command after every agent change to a model, view model, or service. If you have a UI test target, ask the agent to run a specific UI test method or class rather than the whole suite when possible, because XCUITest is slow and flaky. The agent can inspect `.xcresult` text output, but it cannot visually inspect the simulator.

Before you commit, have the agent review the unified diff with a focus on three things: Swift concurrency safety, test isolation, and accidental edits to generated code or project files. For unit tests, make sure the agent uses injection rather than global singletons; an in-memory repository or `URLProtocol` stub is usually better than a live network call. For async tests, the agent should use `await` in the test body and avoid `sleep`-based waits.

## Parallel agents with AgentVera for safer iOS work

AgentVera is a desktop app that runs several coding agents' real command line tools side by side in one window, each in its own terminal panel. For Swift and iOS, the most useful parts are git worktrees so agents do not overwrite the same `project.pbxproj`, automatic code review that links findings to file and line before you merge, checkpoints that let you undo an entire agent turn after a bad refactor, and token budgets that stop a long build-fix loop from consuming an entire day. These protections matter more on iOS because Xcode project conflicts and concurrency regressions are expensive to clean up.

## Keep the feedback loop tight

The mental model is simple: Claude Code accelerates the text-based parts of iOS development but does not replace Xcode, the simulator, or your judgment. Keep the CLAUDE.md current, insist on small diffs and real test runs, and review concurrency and project file changes carefully. For a practical checklist, see [Claude Code best practices: a practical checklist](/en/blog/claude-code-best-practices/).

## Frequently asked questions

**Can Claude Code edit an Xcode project file directly?** Yes, but it should not edit project.pbxproj manually unless you explicitly ask. For normal Swift and iOS tasks, keep it out of the project file and use Xcode or scripts for target and scheme changes.

**How do I tell Claude Code which build and test commands to use for my iOS app?** Put the commands in a CLAUDE.md file at the repository root. Include the exact xcodebuild project, scheme, and destination, plus swift test for any SPM packages and the lint command you use.

**Does Claude Code work with both SwiftUI and UIKit?** Yes. SwiftUI is often easier because the view hierarchy lives in Swift files. UIKit works as well, but storyboards and xibs are less useful as a change surface; prefer code-based UI or keep those files out of the task unless required.

**How can I run several Claude Code agents on one iOS project without merge conflicts?** Use separate git worktrees for each agent and never let them edit project.pbxproj at the same time. AgentVera can run each agent in its own worktree and provide code review and checkpoints to make this safer.

---

**About AgentVera.** AgentVera is a desktop app for macOS, Windows and Linux, built by Solviera Teknoloji. It runs 18 AI coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) side by side, per project, in real terminals with the user's own CLI installs and logins. The free plan has unlimited agents. Download: https://agentvera.dev/en/download/ · Pricing: https://agentvera.dev/en/pricing/
