Build and run on the iOS Simulator
Prefer the XcodeBuildMCP tools from this plugin; fall back to xcodebuild and xcrun simctl when the MCP server is unavailable.
Workflow
- Discover: find the
.xcworkspace/.xcodeproj(prefer the workspace when both exist), then list schemes and available simulators. CLI fallback:xcodebuild -list -workspace App.xcworkspacexcrun simctl list devices available
- Pick a destination: choose one simulator and reuse it for the whole session. Boot it if needed (
xcrun simctl boot <UDID>). - Build: with the MCP server use its simulator build tools. CLI fallback:
xcodebuild -workspace App.xcworkspace -scheme App \ -destination 'platform=iOS Simulator,id=<UDID>' \ -derivedDataPath build/DerivedData build - Install and launch: use the MCP build-and-run tool, or
xcrun simctl install <UDID> <path/to/App.app>thenxcrun simctl launch <UDID> <bundle-id>. - Verify: take a screenshot (
xcrun simctl io <UDID> screenshot out.png) and capture logs (xcrun simctl spawn <UDID> log stream --predicate 'subsystem == "<bundle-id>"'). To interact with the running app, switch to theios-simulator-ui-automationskill.
Reading failures
- Read the first
error:line, not the last; later errors are usually cascades. - Filter raw output with
grep -E "error:|warning:|\*\* BUILD", or pipe throughxcbeautifyif installed. - "No such module": resolve packages (
xcodebuild -resolvePackageDependencies) and rebuild for the same destination. - Signing errors on a simulator build: add
CODE_SIGNING_ALLOWED=NO. For device or archive signing seeios-signing-troubleshooting. - Stale state: delete the derived data folder you passed with
-derivedDataPathbefore blaming the code.
Tests
xcodebuild test -workspace ... -scheme ... -destination 'platform=iOS Simulator,id=<UDID>' -resultBundlePath build/Test.xcresult
then inspect failures with xcrun xcresulttool get test-results summary --path build/Test.xcresult.
Rules
- Never hand-edit
project.pbxprojunless there is no alternative; prefer Xcode, XcodeGen or Tuist configuration. - Keep derived data inside the repo's ignored build directory so runs stay reproducible.


