# opencode for Swift and iOS: A Practical Guide

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

Use opencode in Swift and iOS projects with AGENTS.md, Xcode, SPM, XCTest, SwiftUI and UIKit. Concrete workflow, prompts, testing, and multi-agent tips.

**In short:**

- opencode works from the project root and reads AGENTS.md, so put your xcodebuild, swift test, and SwiftLint commands there.
- Keep prompts small and specific, then require the agent to run XCTest or xcodebuild and show the output after each change.
- For parallel work, run agents in separate git worktrees to avoid conflicts and review diffs before merging any Swift or iOS change.

opencode is a coding agent you start with `opencode` in your Swift or iOS project root. It reads project instructions from AGENTS.md and can edit SwiftUI, UIKit, Swift Package Manager manifests, and XCTest files directly. This guide covers setup, prompts, testing, and multi-agent workflows for production iOS code. See [opencode](/en/agents/opencode/) for the agent itself.

## Why opencode fits Swift and iOS development

Unlike a GUI-only assistant, opencode works in the terminal next to your Xcode project, so it can use the same build and test commands you already run. That matters for iOS because `xcodebuild`, `xcrun simctl`, `swift test`, and SwiftLint give reproducible verification without clicking through Xcode. It reads and writes plain Swift files, including SwiftUI view builders, UIKit view controllers, actors, and async/await code, and it can reason about module boundaries and access control. Because it works from the project root, it also sees Package.swift, test targets, and asset catalogs, making it feasible to ask for a full change and have it run the relevant XCTest suite.

## Making AGENTS.md work for an iOS project

The single highest-leverage step is a project-specific AGENTS.md. Keep it short and concrete: build commands, test commands, lint commands, folder layout, and rules that prevent it from damaging `.xcodeproj` files or violating your iOS target.

A realistic AGENTS.md for a SwiftUI app using SPM looks like this:

```markdown
# AGENTS.md

## Build and test
- Build: xcodebuild -project MyApp.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16' build
- Run tests: xcodebuild test -project MyApp.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16'
- Swift package tests: swift test
- Lint: swiftlint --strict

## Folder conventions
- MyApp/Sources/Features/ for SwiftUI screens and view models
- MyApp/Sources/Services/ for networking, persistence, and system integrations
- MyApp/Sources/Models/ for value types and domain models
- MyAppTests/ for XCTest unit tests

## Rules
- Target iOS 16 or later unless asked otherwise
- Use async/await and actors; do not introduce new callback-based APIs
- Keep SwiftUI views in their own files, named after the view
- Do not modify MyApp.xcodeproj/project.pbxproj directly; if a project file change is needed, list it in the response and wait for approval
- Before finishing a change, run the smallest relevant test target and include the command output
```

This file removes ambiguity about simulator destination, test scope, and coding style. If you use Tuist or XcodeGen, point the agent to the generated project and tell it to edit the YAML or Swift generator instead of the `.xcodeproj` file. For the agent’s general workflow, see [How to use opencode: a step-by-step guide](/en/blog/how-to-use-opencode/).

## Working loop and example prompts for Swift and iOS tasks

Use the same loop as a careful coworker: agree on the change, make a small edit, run the focused test or build command, review the diff, then iterate. Do not ask for broad rewrites of both SwiftUI and UIKit code in one prompt.

Example prompts:

- `In MyApp/Sources/Features/ProfileView.swift, add a loading state driven by an async function that fetches a profile from the existing ProfileService protocol. Keep the current SwiftUI layout and add a retry button that calls the same function. Do not change navigation.`
- `Refactor MyApp/Sources/Services/APIClient.swift to use async/await. Replace the completion handlers in the three call sites under MyApp/Sources/Features/ and update their tests. Keep the public method names unless a rename is clearly safer.`
- `Add unit tests for OrderCalculator in MyAppTests/OrderCalculatorTests.swift. Cover an empty order, one item, multiple items with discounts, and rounding. Run swift test and fix any failures.`
- `Fix the retain cycle in MyApp/Sources/Services/LiveLocationService.swift. Use [weak self] where appropriate and confirm no other closure captures self strongly. Run xcodebuild test -scheme MyApp and report warnings.`

After each prompt, review `git diff` for changes to `.pbxproj`, Info.plist, or entitlements before accepting.

## Where opencode excels and where it struggles in Swift and iOS

The agent handles many changes well: adding SwiftUI screens, converting callback APIs to async/await, writing XCTest cases, adding SPM dependencies, moving files between targets, and fixing compiler errors. It is less reliable on Xcode project file edits, storyboard XML, code signing, and changes that depend on simulator state.

| Task | Good prompt focus | What to review closely |
|------|-------------------|------------------------|
| Add a SwiftUI view | Give exact file, model or service contract, iOS target | Ensure the view compiles with previews; avoid accidental ObservableObject misuse |
| Refactor to async/await | Point to call sites and tests | Check actor isolation, cancellation, and error mapping |
| Add XCTest coverage | Specify edge cases and target | Confirm tests are in the right target and use @MainActor only when needed |
| Add an SPM dependency | Give package URL and target | Review Package.resolved and version pinning; ensure no duplicate module |
| Modify UIKit code | Include file and behavior; mention Auto Layout constraints | Look for missing translatesAutoresizingMaskIntoConstraints, retain cycles, and main-thread assumptions |

Pitfalls specific to Swift and iOS:

- `.xcodeproj` diffs from the agent are hard to review; restrict direct edits.
- SwiftUI previews may fail in CI because the agent drops `#Preview` or uses unavailable APIs.
- Availability: the agent may use iOS 17+ APIs when your target is iOS 16. State the minimum target.
- Concurrency: it sometimes marks types `@MainActor` too broadly, causing deadlocks or over-isolation.
- ARC: closure captures can create retain cycles, especially in UIKit delegates and service callbacks.
- Tests: async tests need proper `await` and may require `@MainActor` if touching SwiftUI state.

## Testing and verification with XCTest and xcodebuild

Make the agent own verification, not just code generation. In the prompt, require the exact command: `xcodebuild test`, `swift test`, or `swiftlint --strict`. Ask it to include the command output in its response and to stop on the first failure instead of generating more changes.

For an app target, use `xcodebuild test -project MyApp.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16'`. For SPM packages, `swift test` is faster and avoids simulator boot. If the project uses async/await, have the agent run tests that cover cancellation and actor isolation, not only happy paths.

Review the diff for anything that touches code signing, entitlements, Info.plist, or the `.xcodeproj`. Prefer `git diff --stat` first, then `git diff` for source files.

## Running multiple agents on one Swift and iOS repo with AgentVera

When a single `opencode` session is too slow for parallel work, AgentVera runs multiple coding agents' real command line tools, including opencode, side by side in separate terminal panels. For Swift and iOS, the most useful parts are separate git worktrees so agents do not overwrite each other’s project files, automatic code review that links findings to file:line, and checkpoints that let you undo one agent’s turn and replay it. Token budgets also help because Xcode builds and simulator tests can consume many turns quickly.

## Wrap up: keeping opencode productive in an iOS team

opencode becomes a reliable Swift and iOS contributor when you give it a precise AGENTS.md, small prompts, and a hard rule to run XCTest or xcodebuild after each change. Review diffs carefully around project files and concurrency code, and use parallel agents with separate worktrees when you need more throughput. With that loop, it fits into an existing Xcode team without replacing the human review step.

## Frequently asked questions

**How do I start opencode in a Swift and iOS project?** Run opencode in the project root after creating an AGENTS.md. The file should include your xcodebuild or swift test command, simulator destination, and rules such as not editing the .xcodeproj directly.

**Can opencode work with both SwiftUI and UIKit?** Yes. It edits plain Swift files for both frameworks. Be explicit about the iOS deployment target, the module, and whether you want SwiftUI views, UIKit view controllers, or a mix, because it can otherwise mix APIs incorrectly.

**How do I prevent opencode from breaking my Xcode project file?** Tell it in AGENTS.md to avoid modifying MyApp.xcodeproj/project.pbxproj directly. If a target or file must be added, ask it to describe the change first and use a generator such as Tuist or XcodeGen when available. Always review project file diffs before committing.

**How do I run tests with opencode?** Instruct it to run xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16' or swift test for package targets. Require the agent to include the command output, then let it fix failing tests and rerun until green.

---

**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/
