Why an iOS coding agent needs a real Mac
An agent can write Swift anywhere. It can only build, run, and see an iOS app on a Mac. That gap is the whole reason iOS work needs a Mac in the loop. It is also the reason an agent with a Mac gets so much better. It can check its own work. This page lists what is macOS-only, then gives the loop we set up for agents on our machines.
What only happens on macOS
- Building the app. xcodebuild and Xcode exist only on macOS. A Linux box can compile Swift packages and server-side Swift. It cannot produce an iOS app.
- Running it. The iOS Simulator is part of Xcode. No simulator, no way to run the app the agent just changed.
- Seeing it. A screenshot of the running app is how an agent finds out the layout broke. That needs the simulator.
- UI tests. XCUITest drives the app on a simulator or device. macOS only.
- Signing and uploading. Code signing, provisioning profiles, and uploads to App Store Connect all go through Apple's tools on macOS.
So an agent on Linux can edit your Swift files and guess. An agent on a Mac can edit, build, run, look, and fix. The second one is the useful one.
The loop, step by step
Set this up once and put the commands in your agent's instructions file so it uses them without being told each time. First, find a simulator and boot it.
xcrun simctl list devices available xcrun simctl boot "iPhone 16"
Build for that simulator. Replace the scheme with yours.
xcodebuild -scheme MyApp \ -destination 'platform=iOS Simulator,name=iPhone 16' \ -derivedDataPath build \ build
Install and launch the build.
xcrun simctl install booted build/Build/Products/Debug-iphonesimulator/MyApp.app xcrun simctl launch booted com.example.MyApp
Take a screenshot the agent can read.
xcrun simctl io booted screenshot /tmp/screen.png
Claude Code and Codex can both open an image file. Tell the agent to take a screenshot after every UI change and describe what it sees before deciding it is done. That one instruction catches most layout mistakes.
Run the tests the same way
xcodebuild -scheme MyApp \ -destination 'platform=iOS Simulator,name=iPhone 16' \ -derivedDataPath build \ test
The derived data path matters. Keeping it inside the project folder means the second build is incremental and takes seconds instead of minutes. An agent that waits four minutes per build does a quarter of the work.
Put the loop in the instructions file
Both agents read a file in the repository root for project instructions. Claude Code reads CLAUDE.md and Codex reads AGENTS.md. Put the loop there so every session starts with it.
## Building and checking this app - Build: xcodebuild -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16' -derivedDataPath build build - Run: xcrun simctl install booted build/Build/Products/Debug-iphonesimulator/MyApp.app && xcrun simctl launch booted com.example.MyApp - Look: xcrun simctl io booted screenshot /tmp/screen.png, then open the image - After any UI change, build, run, and look before saying it is done. - Tests: same xcodebuild command with test instead of build.
Things that trip agents up
- Xcode not selected. After installing a new Xcode, run xcode-select to point at it, or xcodebuild uses the old one.
- Simulator not booted. The launch command fails with a vague error. Boot it first and keep it booted.
- Runtime not installed. A fresh Xcode has no iOS runtime until you download one. That download is several gigabytes and needs to happen before the agent starts.
- No login session. The simulator is a GUI application. On a headless machine with nobody logged in, it will not start. The agent's user needs an active desktop session, which is why automatic login matters on an unattended Mac.
What we set up for you
On an agent Mac from us, Xcode is installed with an iOS runtime downloaded. The agent user has an always-on desktop session. Claude Code and Codex are waiting for your sign-in. Add the loop above to your instructions file and the agent can build and see your app from the first task. The capabilities guide covers what else works on the machine and what does not.
Frequently asked questions
Can Claude Code build an iOS app on Linux?
+
No. It can edit Swift files on Linux, and it can compile Swift packages that do not depend on Apple frameworks. Building an iOS app requires Xcode, which only runs on macOS.
Does the agent need a physical iPhone?
+
Not for most work. The simulator covers building, running, screenshots, and UI tests. A device is needed for things like camera, push notifications, and performance on real hardware.
Can the agent take screenshots of the simulator?
+
Yes, with the simctl screenshot command, as long as a simulator is booted and the agent's user has a desktop session. The agent can then open the image and read it.
Which Xcode version will the agent use?
+
Whichever one xcode-select points at. Pin it in your instructions file and, on a machine with several versions, tell the agent to check before building.