# How the Swift Host Executable Manages the VM Lifecycle in vphone-cli

> Learn how the Swift host executable in vphone-cli manages the VM lifecycle. Discover its role in orchestrating VM configuration, vsock channel setup, and shutdown.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: internals
- Published: 2026-09-10

---

**The Swift host executable in vphone-cli orchestrates the virtual iPhone's entire lifecycle—from CLI option parsing and VM configuration to vsock channel establishment and graceful shutdown—through a centralized `VPhoneAppDelegate` that coordinates `VPhoneVirtualMachine`, `VPhoneControl`, and UI components.**

The **vphone-cli** repository provides a pure-Swift macOS host application that virtualizes iOS devices using Apple's Virtualization framework. Understanding how the Swift host executable manages the VM lifecycle reveals the precise sequence of configuration, validation, and communication steps required to boot and maintain a virtual iPhone instance.

## Application Launch and CLI Parsing

### Entry Point and Signal Handling

The executable enters through [`main.swift`](https://github.com/Lakr233/vphone-cli/blob/main/main.swift), which instantiates `VPhoneAppDelegate` and hands control to the `NSApplication` lifecycle. Inside `VPhoneAppDelegate.applicationDidFinishLaunching`, the host immediately installs a **SIGINT handler** to capture `^C` interrupts and sets the activation policy for GUI or headless operation. The method then launches an asynchronous `Task` to begin VM initialization without blocking the main thread.

```swift
signal(SIGINT, SIG_IGN)
let src = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main)
src.setEventHandler {
    print("\n[vphone] SIGINT — shutting down")
    NSApp.terminate(nil)          // Triggers applicationWillTerminate
}
src.activate()
sigintSource = src

```

### Resolving Boot Options

Before constructing the VM, the host calls `VPhoneBootCLI.resolveOptions()` to transform command-line arguments into a structured `VPhoneVirtualMachine.Options` struct. This object encapsulates critical paths including the disk image, NVRAM, ROM, SEP storage, and display geometry required by the Virtualization framework.

## VM Construction and Hardware Configuration

### Platform Initialization

The `VPhoneVirtualMachine.init(options:)` method, located in [`VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift), builds the complete hardware model. It loads or generates a persistent `VZMacMachineIdentifier`, configures auxiliary storage, and attaches graphics, audio, networking, serial ports, synthetic battery, and the SEP coprocessor. An optional debug stub is also attached at this stage for macOS 26+ builds.

### Configuration Validation

After assembly, the host validates the entire `VZVirtualMachineConfiguration` before instantiation. This ensures all device attachments conform to Apple Virtualization requirements and prevents late-stage boot failures.

## Boot Sequence and Control Channel Establishment

### Starting the VM with DFU Support

The `start(forceDFU:)` method constructs a `VZMacOSVirtualMachineStartOptions` object and conditionally forces DFU mode based on CLI flags. Calling `virtualMachine.start(options:)` powers on the device, and upon successful boot, the host prints the auto-assigned GDB debug stub port to stdout.

```swift
@MainActor
private func startVirtualMachine() async throws {
    let options = try cli.resolveOptions()
    let vm = try VPhoneVirtualMachine(options: options)      // ← Build & validate
    self.vm = vm
    try await vm.start(forceDFU: cli.dfu)                    // ← Power‑on
    // … UI and control channel setup follows …
}

```

### Establishing the Vsock Control Channel

Once the VM is running, the host creates a `VPhoneControl` instance to communicate with the guest-side `vphoned` daemon over a vsock device using a length-prefixed JSON protocol. Simultaneously, `VPhoneHostControl` starts a vsock server to forward screen captures and expose host services to the guest.

## Runtime UI and Event Management

### Window and Input Setup

If graphics are enabled, the host instantiates `VPhoneWindowController` to manage the VM window, `VPhoneKeyHelper` to translate keyboard input, and menu controllers for file and keychain operations. A screen recorder is also attached to capture the virtual display output.

### Handling Guest Capabilities

The `VPhoneControl` object provides `onConnect` and `onDisconnect` callbacks that synchronize UI state. When the guest advertises capabilities like location services, the host enables location forwarding through `VPhoneHostControl`. The callbacks also trigger optional IPA auto-installation when the connection handshake completes.

```swift
control.onConnect = { [weak mc, weak provider] caps in
    mc?.updateConnectAvailability(available: true)
    if caps.contains("location") { provider?.startForwarding() }
    Task { @MainActor [weak self] in
        await self?.installPackageIfRequested(caps: caps)
    }
}
control.onDisconnect = { [weak mc, weak provider] in
    mc?.updateConnectAvailability(available: false)
    provider?.stopForwarding()
}

```

## Graceful Shutdown and Termination

### Signal-Based Termination

When the user sends SIGINT, the dispatch source handler triggers `NSApp.terminate(nil)`, which calls `applicationWillTerminate`. This method stops the `VPhoneHostControl` vsock server and initiates VM shutdown.

### VM Delegate Callbacks

The `VPhoneVirtualMachine` implements `VZVirtualMachineDelegate` methods `guestDidStop` and `virtualMachine(_:didStopWithError:)` to detect guest-initiated shutdowns or crashes. These handlers print diagnostic messages and exit the process with appropriate status codes.

## Summary

- The **Swift host executable** parses CLI options into structured configuration objects before building the VM.
- `VPhoneVirtualMachine` encapsulates hardware setup, validation, and boot sequencing with optional DFU mode.
- `VPhoneControl` and `VPhoneHostControl` establish bidirectional vsock communication for host-guest coordination.
- UI components wire into the control channel callbacks to reflect VM state and guest capabilities.
- SIGINT handlers and delegate callbacks ensure resources are released during graceful shutdown.

## Frequently Asked Questions

### How does vphone-cli handle interrupt signals during VM operation?

The host installs a `DispatchSource` signal handler for **SIGINT** in `VPhoneAppDelegate.applicationDidFinishLaunching`. When triggered, it calls `NSApp.terminate(nil)`, which invokes `applicationWillTerminate` to stop the `VPhoneHostControl` server and clean up resources before exiting.

### What configuration does the Swift host validate before starting the VM?

During `VPhoneVirtualMachine.init(options:)`, the host validates the complete `VZVirtualMachineConfiguration` including the hardware model, machine identifier, graphics device, audio interface, network attachment, serial ports, synthetic battery, SEP coprocessor, and debug stub to ensure compatibility with the Virtualization framework.

### How does the host communicate with the guest iOS system?

After boot, the host opens a vsock connection through **VPhoneControl** to speak a length-prefixed JSON protocol with the guest daemon `vphoned`. A separate `VPhoneHostControl` component hosts a vsock server that provides screen capture forwarding and host services to the guest.

### Where is the debug stub port information displayed?

When running on macOS 26+, the `VPhoneVirtualMachine.start(forceDFU:)` method prints the auto-assigned **GDB debug stub port** to standard output immediately after the VM successfully boots, allowing developers to attach debuggers to the virtual iPhone.