iOS Simulator Driver¶
jumpstarter-driver-iossimulator manages a simulator on a local macOS exporter.
It provides a power child for lifecycle control and an ios child for the
shared iOS client, backed by an operator-installed idb_companion.
Installation¶
$ pip3 install --extra-index-url https://pkg.jumpstarter.dev/simple jumpstarter-driver-iossimulator
The exporter requires a logged-in macOS session, the full
Xcode app selected as the active developer
directory (sudo xcode-select -s /Applications/Xcode.app; the standalone
command-line tools lack simctl), an iOS 17.4+ simulator runtime, and
idb_companion. Install an idb client on each
macOS or Linux client. External tools are installed separately under their
respective licenses; the driver does not bundle or download them.
For Xcode 27, use a companion containing the upstream display-activity fallback;
released companion 1.6.2 cannot capture screenshots on that runtime. Keep the
companion executable with its distribution’s adjacent frameworks and resource
bundles, and set idb_companion to its absolute path when needed.
Configuration¶
export:
simulator:
type: jumpstarter_driver_iossimulator.driver.IosSimulator
config:
device_type: com.apple.CoreSimulator.SimDeviceType.iPhone-18-Pro
runtime: com.apple.CoreSimulator.SimRuntime.iOS-27-0
Find available identifiers with xcrun simctl list devicetypes and
xcrun simctl list runtimes. Configure either a new simulator or a golden source:
Parameter |
Description |
|---|---|
|
Device type and iOS runtime for a new simulator |
|
Dedicated device set and simulator UUID to clone instead |
A golden source must remain shutdown and unchanged while cloning. The driver leaves it intact and rejects the user’s default CoreSimulator device set as a source.
Optional parameter |
Default |
Description |
|---|---|---|
|
|
Simulator name |
|
|
Existing writable directory for private state; use a short path for Unix sockets |
|
|
Xcode tool executable |
|
|
Companion executable |
|
|
Metadata and creation timeout in seconds |
|
|
Boot and readiness timeout in seconds |
|
|
Companion readiness timeout in seconds |
|
|
Shutdown, deletion and process-stop timeout in seconds |
|
Unconfigured |
HTTPS provider class and options from trusted exporter configuration |
Usage¶
Inside a local or leased Jumpstarter shell:
j simulator power on
j simulator ios info
j simulator ios -- idb describe --json
j simulator ios -- idb install /path/to/YourApp.app
j simulator power off
Use j simulator ios serve to keep a local companion endpoint open for an
external idb process, or j simulator ios connect to register it with idb.
The Python API supports the same transport context managers as physical devices:
from jumpstarter.common.utils import serve
from jumpstarter_driver_iossimulator.driver import IosSimulator
driver = IosSimulator(
device_type="com.apple.CoreSimulator.SimDeviceType.iPhone-18-Pro",
runtime="com.apple.CoreSimulator.SimRuntime.iOS-27-0",
)
with serve(driver) as simulator:
simulator.power.on()
with simulator.ios.serve() as endpoint:
print(endpoint) # Pass to idb's --companion option.
simulator.power.off(destroy=True)
power.on() is idempotent. power.off() stops the companion and simulator while
preserving the lease’s data; another on() reuses it. A failed first on()
removes the partially created simulator; a failed restart only stops it, keeping
the lease’s data for a retry. off(destroy=True), reset and session close delete
the owned device set. power.read() is unsupported.
Optional HTTPS service¶
A trusted exporter configuration can add an HTTPS service for the lease’s
simulator by naming an HttpServiceProvider class and its options in the
simulator’s config:
http_service:
provider: your_package.services.YourProvider
options: {}
Clients use the generic ios.https() context manager or
j simulator ios https -- COMMAND; they cannot select the provider, its
executable, host address or options. The service starts when HTTPS metadata is
requested after power.on().
with simulator.ios.https() as endpoint:
url = endpoint.url
context = endpoint.ssl_context()
metadata = endpoint.metadata
The endpoint exposes its URL, public CA file and the provider’s metadata. Keep
certificate and hostname verification enabled. The CLI passes
JUMPSTARTER_IOS_HTTPS_URL, JUMPSTARTER_IOS_HTTPS_CA_FILE and
JUMPSTARTER_IOS_HTTPS_METADATA to the command. The client API is shared with
the iOS device driver.
Security and limitations¶
Each lease owns a private device set and companion Unix socket. Lifecycle
commands explicitly select that set; failures retain ownership when cleanup
must be retried. Core lifecycle uses simctl without launching Simulator.app or
Device Hub. Only local macOS execution is supported.
The owning exporter holds a lock on its lease directory. If an exporter exits
without cleanup, for example after a crash, the next lease or session reset in
the same state_dir shuts down and deletes that lease’s simulators, stops
processes still using its directory, such as its companion and HTTP service,
and removes it. Live leases and directories without a lease lock are never touched.
Simulators share the Mac’s network namespace, so arbitrary TCP forwarding is
unavailable. A configured HTTP provider is trusted exporter code and must
restrict access to its simulator. Its constructor must clean partial resources
on failure; its idempotent close() must revoke streams and remove owned state.
API Reference¶
- class jumpstarter_driver_iossimulator.driver.IosSimulator¶
Manage a local macOS simulator in a private device set.
Configure
device_typeandruntimeto create a simulator, orgolden_device_setandgolden_udidto clone a shutdown source. Power off preserves lease data; destroy, reset and close remove it. Xcode and idb_companion must be installed on the exporter.
- class jumpstarter_driver_iosdevice.client.IosDeviceClient
- connect(protocol: str | None = None, *, port: int = 0, usbfluxctl: str = 'usbfluxctl', idb: str = 'idb', timeout: float = 60.0) Generator[str, None, None]
Attach with the user’s usbfluxctl or idb and detach on exit.
The user installs and runs usbfluxd before attaching a usbmux endpoint. Cleanup also covers a timed out or failed attach, and stays bounded.
- https(*, port: int = 0) Generator[HttpsEndpoint, None, None]
Expose the configured HTTPS service with its public CA and metadata.
The client does not interpret provider metadata or configure tools. Closing the context removes its listener and CA files. The exporter owns service resources until lease teardown or reset.
- serve(protocol: str | None = None, *, port: int = 0) Generator[str, None, None]
Serve a protocol on IPv4 loopback without invoking device tools.
The native protocol is the first one advertised by the target.
port=0selects an unused local port. The yielded endpoint is127.0.0.1:port.
- class jumpstarter_driver_iossimulator.http_service.HttpServiceProvider¶
An HTTPS service scoped to one simulator lease.
Constructors must remove partial resources before raising.
closemust be idempotent and revoke existing streams as well as prevent new ones. A close failure leaves the provider and device set owned for a cleanup retry. Providers must not discover, stop or mutate resources outside their context.- abstractmethod close() None¶
Revoke streams, stop owned processes and remove private state.
- abstractmethod connect()¶
Return an async context manager yielding the encrypted byte stream.
- abstractmethod metadata() dict¶
Return public ca_certificate PEM and a JSON metadata object.