Back to Skills

iOS Simulator

Build, navigate, and test iOS apps via simulator automation with XcodeBuild integration

iosxcodemobiletestingautomation
By conorluddy
1.1k76Updated 3 weeks agoPythonMIT

Skill Content

# iOS Simulator Skill

Automate iOS app building, navigation, and testing via the iOS Simulator.

## Overview

This skill enables Claude Code to interact with iOS simulators for:

- **Building** - Compile and run iOS apps on simulator
- **Navigation** - Interact with UI elements, tap buttons, scroll
- **Testing** - Run UI tests and validate app behavior
- **Screenshots** - Capture simulator screenshots for debugging

## Installation

Clone the skill to your Claude Code configuration:

```bash
git clone https://github.com/conorluddy/ios-simulator-skill.git ~/.claude/skills/ios-simulator
```

## Requirements

- Xcode installed with iOS simulators
- XcodeBuildMCP server (recommended)
- macOS development environment

## Features

### Build and Run
- Build iOS projects with xcodebuild
- Launch apps on specific simulator devices
- Handle build errors and warnings

### UI Automation
- Tap elements by accessibility identifier
- Input text into text fields
- Scroll and swipe gestures
- Wait for elements to appear

### Testing Support
- Run XCUITest test suites
- Capture test results and failures
- Generate test coverage reports

## Example Usage

"Build and run the app on iPhone 15 Pro simulator"
"Tap the login button and enter test credentials"
"Run all UI tests and show me any failures"

## Repository

[github.com/conorluddy/ios-simulator-skill](https://github.com/conorluddy/ios-simulator-skill)

How to use

  1. Copy the skill content above
  2. Create a .claude/skills directory in your project
  3. Save as .claude/skills/ios-simulator.md
  4. Use /ios-simulator in Claude Code to invoke this skill

Ask DeepWiki

iOS Simulator Skill for Claude Code

Production-ready skill for building, testing, and automating iOS apps. 27 scripts optimized for both human developers and AI agents.

(If you'd prefer an MCP, XC-MCP)

Xcode Build + Simulator Automation

This skill covers both sides of iOS development:

  • Xcode builds via xcodebuild — compile, test, and parse results with progressive error disclosure
  • Simulator interaction via xcrun simctl and idb — semantic UI navigation, accessibility testing, device lifecycle

If you only need Xcode build tooling without the simulator scripts, see the plugin version: xclaude-plugin

Installation

Via Plugin Marketplace (Recommended)

In Claude Code:

/plugin marketplace add conorluddy/ios-simulator-skill
/plugin install ios-simulator-skill@conorluddy

Via Git Clone

# Personal installation
git clone https://github.com/conorluddy/ios-simulator-skill.git ~/.claude/skills/ios-simulator-skill

# Project installation
git clone https://github.com/conorluddy/ios-simulator-skill.git .claude/skills/ios-simulator-skill

Restart Claude Code. The skill loads automatically.

Prerequisites

  • macOS 12+
  • Xcode Command Line Tools (xcode-select --install)
  • Python 3
  • IDB (optional, for interactive features: brew tap facebook/fb && brew install idb-companion)
  • Pillow (optional, for visual diffs: pip3 install pillow)

Features

Xcode Build with Progressive Disclosure

The build_and_test.py script wraps xcodebuild with token-efficient output. A build returns a single summary line with an xcresult ID:

Build: SUCCESS (0 errors, 3 warnings) [xcresult-20251018-143052]

Then drill into details on demand:

python scripts/build_and_test.py --get-errors xcresult-20251018-143052
python scripts/build_and_test.py --get-warnings xcresult-20251018-143052
python scripts/build_and_test.py --get-log xcresult-20251018-143052

This keeps agent conversations focused — no walls of build output unless you ask for them.

Simulator Navigation via Accessibility

Instead of fragile pixel-coordinate tapping, all navigation uses iOS accessibility APIs to find elements by meaning:

# Fragile — breaks if UI changes
idb ui tap 320 400

# Robust — finds by meaning
python scripts/navigator.py --find-text "Login" --tap

The accessibility tree gives structured data (element types, labels, frames, tap targets) at ~10 tokens default output vs 1,600-6,300 tokens for a screenshot. See AI-Accessible Apps for more on why accessibility-first navigation matters for AI agents.

Screenshot Token Optimization

When screenshots are needed (visual verification, bug reports, diffs), the skill automatically resizes and compresses them to minimize token cost. Default output across all 27 scripts is 3-5 lines — 96% reduction vs raw tool output.

TaskRaw ToolsThis SkillSavings
Screen analysis200+ lines5 lines97.5%
Find & tap button100+ lines1 line99%
Login flow400+ lines15 lines96%

All 27 Scripts

Every script supports --help and --json. See SKILL.md for the complete reference.

Build & Development

ScriptWhat it doesKey flags
build_and_test.pyBuild Xcode projects, run tests, parse xcresult bundles--project, --scheme, --test, --get-errors, --get-warnings
log_monitor.pyReal-time log monitoring with severity filtering--app, --severity, --follow, --duration

Device State

ScriptWhat it doesKey flags
appearance.pySwitch dark mode, dynamic type, locale, region--theme, --text-size, --locale, --region, --reset
location.pySimulate GPS coordinates and run built-in scenarios--lat, --lng, --city, --gpx, --list-scenarios, --clear

Navigation & Interaction

ScriptWhat it doesKey flags
screen_mapper.pyAnalyze current screen, list interactive elements--verbose, --hints
navigator.pyFind and interact with elements semantically--find-text, --find-type, --find-id, --tap, --enter-text
gesture.pySwipes, scrolls, pinches, long press, pull to refresh--swipe, --scroll, --pinch, --long-press, --refresh
keyboard.pyText input and hardware button control--type, --key, --button, --clear, --dismiss
app_launcher.pyLaunch, terminate, install, deep link apps--launch, --terminate, --install, --open-url, --list

Testing & Analysis

ScriptWhat it doesKey flags
accessibility_audit.pyWCAG compliance checking on current screen--verbose, --output
visual_diff.pyCompare two screenshots for visual changes--threshold, --output, --details
test_recorder.pyAutomated test documentation with screenshots--test-name, --output
app_state_capture.pyDebugging snapshots (screenshot, hierarchy, logs)--app-bundle-id, --output, --log-lines
sim_health_check.shVerify environment (Xcode, simctl, IDB, Python)
model_inspector.pyInspect Core Data / SwiftData models from project files--project-path, --raw, --show-versions
container.pyInspect app sandbox: list, cat, UserDefaults, Core Data, export--ls, --cat, --userdefaults, --core-data-path, --export
hang_watcher.py (HangBuster)Record + summarise os_log hang events with progressive disclosure (session mode + raw NDJSON + legacy stream); auto-restart on stream death, automatic disk-cap cleanup--start [--raw-capture --max-size-mb N --no-gzip], --stop, --get-details, --list-sessions, --diff, --budget-tokens, --auto-sample (legacy: --watch, --since)
localization_audit.pyAudit .xcstrings catalogs for missing keys, unused keys, placeholder mismatches--catalog, --source, --strict

Permissions & Environment

ScriptWhat it doesKey flags
clipboard.pyCopy text to simulator clipboard for paste testing--copy, --test-name
status_bar.pyOverride status bar (time, battery, network)--preset, --time, --battery-level, --clear
push_notification.pySend simulated push notifications--bundle-id, --title, --body, --payload
privacy_manager.pyGrant, revoke, reset app permissions (13 services)--bundle-id, --grant, --revoke, --reset

Device Lifecycle

ScriptWhat it doesKey flags
simctl_boot.pyBoot simulators with readiness verification--name, --wait-ready, --timeout, --all, --type
simctl_shutdown.pyGracefully shutdown simulators--name, --verify, --all, --type
simctl_create.pyCreate simulators by device type and OS version--device, --runtime, --list-devices
simctl_delete.pyDelete simulators with safety confirmation--name, --yes, --all, --old
simctl_erase.pyFactory reset without deletion--name, --verify, --all, --booted

Configuration

Every operational limit — timeouts, output caps, polling intervals, cache size, post-action delays — is tunable via an IOS_SIM_* environment variable. Defaults are tuned for local development on Apple Silicon. Raise them on slow CI runners, large monorepos, or accessibility audits over complex screens. Lower them when you need faster failure or tighter token budgets.

There's a universal tradeoff to keep in mind:

  • Higher caps / longer timeouts → fewer false failures, more complete diagnostics, more tokens consumed by AI agents and slower failures when something is genuinely broken.
  • Lower caps / shorter timeouts → faster feedback, tighter token usage, risk of silently dropped errors or premature timeouts on legitimately slow operations.

Boot & lifecycle timeouts

How long to wait on xcrun simctl operations.

VariableDefaultTradeoff
IOS_SIM_BOOT_TIMEOUT300 (s)Wait for simulator readiness after boot. Lower → faster failure on broken sims. Higher → survives cold-start on slow CI runners (GitHub-hosted macOS can need 4–6 min).
IOS_SIM_BOOT_SUBPROCESS_TIMEOUT60 (s)Timeout for the simctl boot call itself (before readiness polling starts). Rarely needs changing; bump only if you see Boot command timed out on resource-starved CI.
IOS_SIM_ERASE_TIMEOUT90 (s)Wait for factory-reset verification. Larger simulators (lots of installed apps + data) can need more than the old 30s.
IOS_SIM_POLL_INTERVAL0.5 (s)How often to re-check boot/erase state. Lower → more responsive (more CPU). Higher → quieter on slow CI but adds latency to “ready” detection.
IOS_SIM_STATE_SUBPROCESS_TIMEOUT15 (s)Per-subprocess timeout in app_state_capture.py. Bump for apps with very large accessibility trees.

Build & test output caps

build_and_test.py returns counts by default and full details via xcresult ID; these caps govern what's surfaced in human/JSON output before progressive disclosure kicks in.

VariableDefaultTradeoff
IOS_SIM_BUILD_SUMMARY_CAP15Errors / failed tests in the default text summary. Lower → terser default output. Higher → less need to chase xcresult IDs for context.
IOS_SIM_BUILD_VERBOSE_CAP100Errors / warnings in --verbose mode. Mostly relevant for monorepos or first builds with many fixable warnings.
IOS_SIM_BUILD_JSON_CAP50Max errors / failed tests in --json output. Raise for CI dashboards that need exhaustive lists.
IOS_SIM_BUILD_LOG_PREVIEW4000 (chars)Chars of build log included in default output. Higher → more context for failures, more tokens.
IOS_SIM_BUILD_TIMEOUT1800 (s)Hard cap on a single xcodebuild build invocation. Default of 30 min covers most clean builds of large apps; raise for very large monorepos, lower to fail fast in CI when builds are expected to take seconds. Without this, a hung xcodebuild would block forever.
IOS_SIM_TEST_TIMEOUT2700 (s)Hard cap on xcodebuild test. Tests can take significantly longer than builds (45 min default) because of simulator boot + animation delays.
IOS_SIM_INTROSPECT_TIMEOUT60 (s)Timeout for xcodebuild -list and xcrun simctl list introspection calls. These should normally complete in <1s; 60s catches Xcode-toolchain hangs without disrupting cold-start.

Log monitor output

log_monitor.py aggregates os_log output; these caps shape both the text summary and the structured JSON.

VariableDefaultTradeoff
IOS_SIM_LOG_TEXT_SUMMARY15Errors / warnings shown in the text summary. The default surfaces enough for most debugging without flooding terminal output.
IOS_SIM_LOG_LINE_MAX300 (chars)Per-line truncation. Crash messages with full Swift symbol mangling can exceed 200 chars; raise if you see “…” cutting off the actionable bit.
IOS_SIM_LOG_TAIL200 (lines)Recent log lines shown in verbose mode and JSON sample_logs. Also used by xcode log excerpt. Lower for tighter context, higher for richer post-mortems.
IOS_SIM_LOG_JSON_CAP100Max errors / warnings in JSON output. Raise if you're piping into a dashboard that needs the full picture.
IOS_SIM_HANG_PREDICATE(default)Override the os_log predicate used by hang_watcher.py. The default catches Run

View source on GitHub