Skip to main content

SimctlClient

Struct SimctlClient 

Source
pub struct SimctlClient {}
Expand description

Stateless wrapper around xcrun simctl. Methods are free functions in spirit (no instance state beyond optionally-cached xcrun path); kept as a struct for API ergonomics + future caching.

Implementations§

Source§

impl SimctlClient

Source

pub fn new() -> Self

Construct a new client (stateless — equivalent to default()).

Source

pub async fn list_runtimes(&self) -> Result<Vec<SimctlRuntime>, SimctlError>

xcrun simctl list runtimes -jVec<SimctlRuntime>.

Source

pub async fn list_devices(&self) -> Result<Vec<SimctlDevice>, SimctlError>

xcrun simctl list devices -j → flattened Vec<SimctlDevice>.

Source

pub async fn boot(&self, udid: &str) -> Result<(), SimctlError>

xcrun simctl boot <udid> — fire-and-forget boot request.

Source

pub async fn shutdown(&self, udid: &str) -> Result<(), SimctlError>

xcrun simctl shutdown <udid>.

Source

pub async fn current_locale( &self, udid: &str, ) -> Result<Option<String>, SimctlError>

v6.10 c2 — read the sim’s current BCP-47 locale (first entry of NSGlobalDomain AppleLanguages). Returns Ok(None) when the preference is unset (defaults read exits non-zero) or unparseable. Wire format: simctl spawn <udid> defaults read -g AppleLanguages stdout looks like "(\n \"en-US\"\n)\n"; we extract the first quoted token.

Source

pub async fn set_locale( &self, udid: &str, locale: &str, ) -> Result<(), SimctlError>

v6.10 c2 — write AppleLanguages (array) + AppleLocale (scalar) to the sim’s NSGlobalDomain so SpringBoard + apps re-localize on next launch. AppleLocale is BCP-47 with hyphen replaced by underscore (en_US); AppleLanguages is the BCP-47 tag verbatim. The caller must shutdown + reboot the sim for the change to take effect — running apps cache the locale at process start. Insight gol-611 §3 capability.

Source

pub async fn boot_and_wait( &self, udid: &str, timeout: Duration, ) -> Result<(), SimctlError>

Boot + poll device state == “Booted” within timeout. Tries every 500 ms until success or timeout_ms elapses. Idempotent on already-booted devices (xcrun simctl boot 已 booted 返非零, swallow).

Source

pub async fn erase(&self, udid: &str) -> Result<(), SimctlError>

xcrun simctl erase <udid> — wipe device contents.

Source

pub async fn install( &self, udid: &str, app_path: &str, ) -> Result<(), SimctlError>

xcrun simctl install <udid> <app-path> — install a .app bundle.

Source

pub async fn uninstall( &self, udid: &str, bundle_id: &str, ) -> Result<(), SimctlError>

xcrun simctl uninstall <udid> <bundle-id>.

Source

pub async fn terminate( &self, udid: &str, bundle_id: &str, ) -> Result<(), SimctlError>

xcrun simctl terminate <udid> <bundle-id> — kill a running app.

Source

pub async fn launch( &self, udid: &str, bundle_id: &str, ) -> Result<LaunchResult, SimctlError>

xcrun simctl launch <udid> <bundleId> → parse "<bundle>: <pid>".

Source

pub async fn launch_with_args( &self, udid: &str, bundle_id: &str, args: &[String], ) -> Result<LaunchResult, SimctlError>

xcrun simctl launch <udid> <bundleId> -- <arg>... — launch with a process-level argument vector. Empty args is equivalent to Self::launch. v5.2 c2 — maestro yaml launchApp.arguments 同源.

Source

pub async fn launch_with_args_and_env( &self, udid: &str, bundle_id: &str, args: &[String], child_env: &[(&str, &str)], ) -> Result<LaunchResult, SimctlError>

v6.8 c2 — like Self::launch_with_args but also sets SIMCTL_CHILD_* envp on the simctl process so the launched app can read deploy-time vars via ProcessInfo().environment["KEY"]. child_env keys without the SIMCTL_CHILD_ prefix get it added automatically (per compose_child_env semantics). Insight gol-611 §4 — used to prelaunch an app before any openLink so iOS treats the subsequent URL handoff as in-app routing instead of cross-app, side-stepping the SpringBoard “Open in ‘’?” confirmation dialog.

Source

pub async fn open_url(&self, udid: &str, url: &str) -> Result<(), SimctlError>

xcrun simctl openurl <udid> <url> — open a URL on the device.

Source

pub async fn send_push( &self, udid: &str, bundle_id: &str, apns_json_path: &str, ) -> Result<(), SimctlError>

v5.7 c3 — xcrun simctl push <udid> <bundle-id> <apns-json-path>. Deliver an APNS payload to a sim-installed app. The payload file is a JSON document whose top-level dictionary mirrors what an APNS provider would send; aps.alert.body / aps.alert.title surface as banner content and reach the app’s UNUserNotificationCenterDelegate.

Source

pub async fn set_appearance( &self, udid: &str, mode: Appearance, ) -> Result<(), SimctlError>

xcrun simctl ui <udid> appearance <light|dark> — set UI appearance.

Source

pub async fn grant_permission( &self, udid: &str, permission: SimctlPermission, bundle_id: &str, ) -> Result<(), SimctlError>

xcrun simctl privacy <udid> grant <perm> <bundle-id>.

Source

pub async fn revoke_permission( &self, udid: &str, permission: SimctlPermission, bundle_id: &str, ) -> Result<(), SimctlError>

xcrun simctl privacy <udid> revoke <perm> <bundle-id> — explicitly deny the permission. v5.2 c2 — maestro yaml permissions: { x: deny } 同源(grant 反向). 不同于 reset(那是回到 “not determined”).

Source

pub async fn location_set( &self, udid: &str, latitude: f64, longitude: f64, ) -> Result<(), SimctlError>

v5.2 c5 — xcrun simctl location <udid> set <lat>,<lng> — set sim location to a fixed point. maestro setLocation 同源.

Source

pub async fn location_start( &self, udid: &str, points: &[(f64, f64)], speed_mps: Option<f64>, ) -> Result<(), SimctlError>

v5.2 c5 — xcrun simctl location <udid> start [--speed=<m/s>] <waypoints> — interpolate sim location along waypoints. Fire-and-return: simctl injects scenario and returns; sim continues interpolation in background. maestro travel 同源.

Source

pub async fn location_clear(&self, udid: &str) -> Result<(), SimctlError>

v5.2 c5 — xcrun simctl location <udid> clear — reset active location scenario.

Source

pub async fn add_media( &self, udid: &str, paths: &[String], ) -> Result<(), SimctlError>

v5.2 c5 — xcrun simctl addmedia <udid> <path>... — add photos / videos / contacts to sim library. maestro addMedia 同源 (scalar or array form already flattened on adapter side).

Source

pub async fn record_video_start( &self, udid: &str, path: &str, ) -> Result<RecordingHandle, SimctlError>

v5.2 c5 — start recording sim display to path. Spawns xcrun simctl io <udid> recordVideo <path> as a long-running child; returns handle immediately. Caller must pair with Self::record_video_stop for clean SIGINT-and-wait shutdown — dropping the handle would SIGKILL via tokio + lose mp4 trailer.

Source

pub async fn record_video_stop( &self, handle: RecordingHandle, ) -> Result<(), SimctlError>

v5.2 c5 — stop a recording via SIGINT + wait (≤10s). SIGINT lets simctl trap and flush the mp4 trailer; SIGKILL would corrupt output. Timeout escalates to SIGKILL with explicit error mentioning truncation.

Source

pub async fn reset_permission( &self, udid: &str, permission: SimctlPermission, bundle_id: &str, ) -> Result<(), SimctlError>

xcrun simctl privacy <udid> reset <perm> <bundle-id> — return the permission to “not determined” so the next request re-prompts. May terminate a running instance of the target app (Apple behavior) — call before launch, not mid-flow.

Source

pub async fn keychain_reset(&self, udid: &str) -> Result<(), SimctlError>

xcrun simctl keychain <udid> reset — clear all keychain entries.

Source

pub async fn pasteboard_get(&self, udid: &str) -> Result<String, SimctlError>

xcrun simctl pbpaste <udid> — read clipboard contents.

Source

pub async fn pasteboard_set( &self, udid: &str, text: &str, ) -> Result<(), SimctlError>

xcrun simctl pbcopy <udid> — write clipboard contents (via piped stdin).

Source

pub async fn set_reduce_motion( &self, udid: &str, enabled: bool, ) -> Result<(), SimctlError>

Toggle “Reduce Motion” accessibility setting via defaults write.

Source

pub async fn screenshot(&self, udid: &str) -> Result<Vec<u8>, SimctlError>

xcrun simctl io <udid> screenshot <tmpfile> → raw PNG bytes.

Goes through a temp file: current Xcode’s screenshot - does not treat - as stdout — it writes a literal file named - in cwd and emits nothing on stdout (observed on Xcode/iOS 26.5).

Source

pub async fn create_device( &self, name: &str, device_type: &str, runtime_id: &str, ) -> Result<String, SimctlError>

xcrun simctl create <name> <device-type-id> <runtime-id> → udid.

Source

pub async fn delete_device(&self, udid: &str) -> Result<(), SimctlError>

xcrun simctl delete <udid> — delete a simulator device.

Trait Implementations§

Source§

impl Debug for SimctlClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SimctlClient

Source§

fn default() -> SimctlClient

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.