Skip to main content

setup

setup prepares one connected iPhone so that a portal can serve it. With no UDID, it uses the only connected phone or asks you to pick one. With several phones in a non-interactive session, pass the UDID. Running setup again is safe. It checks each step and skips what is already done. It never erases the phone.
Stop the phone’s portal before you run setup or verify. Only one CLI process can own a phone at a time. Use mobilerun-ios stop <udid> for a detached portal, or Ctrl+C for a foreground portal or auto.

What setup does

1

Finds and pairs the phone

Setup connects to the phone over USB. On first use, the phone asks you to Trust This Computer. The host keeps its pairing identity in ~/.mobilerun-ios/pairrecords/.
2

Finishes Setup Assistant, if needed

If the phone is still in Setup Assistant, or was erased, setup can prepare it without erasing it. It activates and supervises the phone, installs the fleet profile with Wi-Fi, and completes Setup Assistant. This needs profile.wifi, supervision_cert, and supervision_key in your configuration. A phone that has finished Setup Assistant skips this step.
3

Chooses the control mode

Setup chooses WDA or native control and saves the choice for this phone. Phones below iOS 27 use WDA. On iOS 27 and later, a phone with no runner gets native control, and --wda selects WDA.
4

Enables Developer Mode

On a phone without a passcode, setup turns Developer Mode on, waits for the restart, and confirms it. On a phone with a passcode, iOS requires you to do it: setup shows the Settings → Privacy & Security → Developer Mode switch. Turn it on and tap Restart. After the restart, unlock the phone, tap Turn On, and enter your passcode. You do not need Xcode for this step.
5

Mounts the developer disk image

The developer disk image (DDI) contains the developer services that automation needs. For iOS 17 and later, setup uses Xcode’s image or downloads one. It has Apple personalize the image for this phone, then mounts it. For iOS 16, it mounts the classic image. Downloads are cached in ~/.mobilerun-ios/devimages/.
6

Signs and installs WDA (WDA mode only)

Setup downloads the prebuilt Mobilerun runner and signs it for this phone with Xcode or App Store Connect. Then it installs it. If iOS asks, trust the developer in Settings → General → VPN & Device Management. Setup then launches the runner to prove that iOS accepts it. An installed Mobilerun runner is kept and not signed again. Use --reinstall to renew it.
7

Checks the result

Setup runs the same checks as verify and reports what is ready. It does not log in and does not start a portal.
Setup cannot tap on-phone prompts for you, such as trust, unlock, and confirmations. In an interactive terminal it waits for you. With --non-interactive, it stops and tells you which action is needed.

Flags

Global flags: --log-level, --verbose / -v, and --tunnel-mode. v0.4.x users: --runner-url and --bundle-id are now --wda-unsigned-url and --wda-bundle-id; see Migrate to v0.5.0.

Examples

Control-mode persistence

Setup saves the selected mode in ~/.mobilerun-ios/devices/<udid>.json, not in config.yaml. verify, portals, auto, macro, and reset use the saved mode. Without a saved mode, phones below iOS 27 use WDA. On iOS 27 and later, an installed runner keeps WDA; otherwise the phone gets native control. MOBILERUN_IOS_REMOTE_XPC_ONLY=true forces native control and false forces WDA, ahead of the saved mode. Setup rejects a --wda choice that conflicts with this variable. Unset it, or make it match, before you change the saved mode.

verify

verify checks one phone and prints a table. It exits non-zero if something is missing or cannot be checked. It does not repair anything. It checks the same mode that setup saved:
  • Device identity and Developer Mode.
  • Mounted developer disk image.
  • In WDA mode: the runner is installed.
  • In native mode: the native services and device capabilities. If a prerequisite is missing, native readiness shows not checked. That does not mean the phone cannot use native control.
Plain verify only shows that the runner is installed. Use --deep to prove that it launches. --deep starts the runner and stops it again; a runner that is already running is left alone. Neither check tests cloud login, the browser stream, or a task. Confirm those in the dashboard.

When verification fails

After a repair, run verify again, start the portal, and confirm streaming and a task in the dashboard.