CalcSnippets Search
iOS 3 min read

`xcrun simctl` Is the iOS Simulator Command Set You Should Learn Before Clicking Around Xcode for an Hour

A practical guide to using `xcrun simctl` to boot simulators, install apps, open deep links, clear state, and debug iOS simulator workflows without wasting time in Xcode menus.

Why this command matters: a lot of iOS debugging time gets wasted on UI clicking when the real problem is not Xcode itself. It is that developers are doing repeatable simulator tasks manually.

If you build for iPhone or iPad regularly, xcrun simctl is one of the fastest ways to stop treating the iOS Simulator like a black box. Apple documents it as the command-line control surface for Simulator devices, and that is exactly how you should think about it: boot, erase, install, uninstall, launch, open URLs, and manage app containers without poking through menus.

Start by listing devices

When you do not know which simulators are available, run:

xcrun simctl list devices

That tells you:

  1. device names
  2. runtime versions
  3. whether they are booted
  4. whether they are shutdown or unavailable

If you only remember one first step, remember this one. A lot of “simulator is broken” problems are actually “you are targeting the wrong runtime or wrong device.”

Boot a simulator from the terminal

Instead of opening Simulator first and clicking around, boot directly:

xcrun simctl boot "iPhone 16 Pro"
open -a Simulator

If the device is already booted, the boot command is harmless. This is especially useful in scripts and repeatable local setup.

You can also target by UDID instead of by name if you want something less ambiguous.

Install and launch your app without hunting for it

Once you have a built .app, install it directly:

xcrun simctl install booted /path/to/MyApp.app

Then launch it by bundle id:

xcrun simctl launch booted com.example.myapp

This matters because it separates build problems from simulator interaction problems. If Xcode looks confused, simctl install and simctl launch often tell you much faster whether the artifact itself is fine.

Test deep links and auth callbacks directly

If your app handles custom schemes or universal-link style flows, you do not need to manually type them in Safari every time. Use:

xcrun simctl openurl booted "myapp://login/callback?token=demo123"

This is one of the best ways to debug:

  1. deep links
  2. OAuth callback handling
  3. app routing
  4. branch-specific test flows

The difference between a flaky manual test and a repeatable one is often just this command.

Wipe bad state when the app gets weird

Simulator state drifts. Caches persist. Broken auth sessions stick around. Developers often waste time debugging “code problems” that are really stale simulator state.

Erase the whole device if you need a clean start:

xcrun simctl erase booted

Or uninstall just your app:

xcrun simctl uninstall booted com.example.myapp

This is a much cleaner debugging move than repeatedly deleting the app by hand and hoping that was enough.

Open the app’s sandbox when debugging files

If you need to inspect files your app wrote, get the container path:

xcrun simctl get_app_container booted com.example.myapp data

You can then open that path in Finder or inspect it from the shell. This is extremely useful for:

  1. SQLite databases
  2. downloaded assets
  3. logs written by the app
  4. caches and preference files

When local storage is part of the bug, this command is usually faster than digging through Xcode’s UI.

A practical debug loop

Here is a clean repeatable simulator loop:

xcrun simctl boot "iPhone 16 Pro"
xcrun simctl uninstall booted com.example.myapp || true
xcrun simctl install booted /path/to/MyApp.app
xcrun simctl launch booted com.example.myapp
xcrun simctl openurl booted "myapp://debug"

That flow turns simulator testing into something scriptable instead of something you perform by memory.

Final recommendation

If you touch iOS often, stop treating Simulator as a purely graphical tool. Learn xcrun simctl for device listing, booting, install, launch, deep-link testing, uninstall, erase, and app-container inspection. The payoff is not only speed. It is repeatability.

Sources

Keep reading

Related guides