Understanding the vphone-cli Architecture: A Modular Swift Virtualization Framework for iOS VMs
The vphone-cli architecture is a modular, layered Swift system built on Apple's Virtualization.framework, separating VM lifecycle management, guest-daemon communication via vsock, UI/menu handling, and firmware patching into loosely coupled subsystems.
vphone-cli is a Swift-only macOS application that creates, configures, and boots virtual iPhone VMs. Its architecture deliberately isolates concerns across eight primary layers, making the codebase testable, extensible, and maintainable. Every major component lives in the sources/vphone-cli/ directory, with additional Python-based firmware patchers in sources/FirmwarePatcher/.
Entry Point and Application Lifecycle
The application bootstrap follows standard macOS patterns with custom VM orchestration layered on top.
VPhoneCLI.swift – Command-Line Parser
Located at sources/vphone-cli/VPhoneCLI.swift, this file parses arguments and launches the NSApplication. It transforms CLI flags into structured options passed to the delegate.
VPhoneAppDelegate.swift – Lifecycle Orchestrator
VPhoneAppDelegate.swift handles the critical startup sequence:
- Configures
NSApplicationand registers SIGINT handlers - Creates
VPhoneVirtualMachinewith injected options - Instantiates
VPhoneWindowControllerfor the main window
The delegate serves as the central coordinator, bridging user intent (CLI or UI) with VM execution.
Virtual Machine Core
The VM layer wraps Apple's VZVirtualMachine with vphone-cli-specific configuration and lifecycle management. All classes here use @MainActor annotation to ensure UI consistency.
VPhoneVirtualMachine.swift
This core wrapper in sources/vphone-cli/VPhoneVirtualMachine.swift manages:
VZVirtualMachineConfigurationassembly- Hardware model integration from
VPhoneHardwareModel - Lifecycle methods:
start(),stop(), and state observation
VPhoneHardwareModel.swift
Located at sources/vphone-cli/VPhoneHardwareModel.swift, this component describes virtual CPU, GPU, memory, and device topology. It uses the Dynamic library to call private Apple APIs for hardware model selection.
VPhoneVirtualMachineView.swift
VPhoneVirtualMachineView.swift provides an NSView subclass wrapping VZVirtualMachineView, handling display rendering and input event forwarding from macOS to the guest iOS system.
Guest-Daemon Communication (vsock)
Communication with the running iOS VM occurs over vsock (port 1337) using a length-prefixed JSON protocol.
VPhoneControl.swift
The host-side client in sources/vphone-cli/VPhoneControl.swift implements:
- Automatic reconnection to the in-VM
vphoneddaemon - Request/response mapping with structured JSON
- Low-level vsock socket management
VPhoneHostControl.swift
VPhoneHostControl.swift acts as a convenience layer, exposing high-level host commands:
- IPA installation forwarding
- File retrieval and upload
- Location synchronization
- Remote shell execution
This subsystem enables the full feature set: file browsing, app installation, location spoofing, and command execution without direct VM manipulation.
UI and Menu System
The interface layer separates window management, menu registration, and specialized interaction handlers.
VPhoneWindowController.swift
VPhoneWindowController.swift hosts the VM view, toolbar configuration, and menu bar orchestration.
VPhoneMenuController.swift
The central hub at sources/vphone-cli/VPhoneMenuController.swift maintains a registry of menu extensions. Each category registers callbacks here, enabling dynamic menu construction.
Specialized Menu Components
Individual files handle specific feature categories:
VPhoneMenuKeys.swift– Hardware key simulationVPhoneMenuLocation.swift– GPS/location controlsVPhoneMenuConnect.swift– Connection stateVPhoneMenuInstall.swift– IPA installation UIVPhoneMenuRecord.swift– Screen recording controlsVPhoneMenuBattery.swift– Battery state simulation
VPhoneKeyHelper.swift
VPhoneKeyHelper.swift translates macOS NSEvent key events into VM key presses for home, power, volume, and other hardware buttons.
SwiftUI File Browser
The VPhoneFileBrowser* files implement a complete file manager:
VPhoneFileBrowserView.swift– SwiftUI view layerVPhoneFileBrowserWindow.swift– Window containerVPhoneFileBrowserModel.swift– Observable data model
These components bind to VPhoneControl for directory listing, upload, and download operations via the vsock daemon.
Firmware and Patch Pipeline
Firmware preparation runs external to the running VM through a hybrid Python/Swift pipeline.
Python-Based FirmwarePatcher
Located under sources/FirmwarePatcher/, these patchers modify:
- iOS kernel images
- Device tree blobs
- Cryptex files
The Swift side remains agnostic to patch implementation details, consuming only the final CFW (custom firmware) image.
VPhoneFWCLI.swift
VPhoneFWCLI.swift provides the CLI frontend for firmware operations:
- Variant selection (regular, developer, jailbreak, experimental)
- Patch pipeline invocation
Disk.imggeneration
The modular patcher design allows new firmware variants without client code changes.
IPA Installation and Code Signing
VPhoneIPAInstaller.swift
VPhoneIPAInstaller.swift at sources/vphone-cli/VPhoneIPAInstaller.swift handles the complete installation flow:
- IPA extraction
- Mach-O binary re-signing via
VPhoneSigner - Payload streaming to VM through
VPhoneControl
VPhoneSigner.swift
VPhoneSigner.swift implements low-level Mach-O signing with codesign-compatible hashes and private entitlement injection.
Auxiliary Utilities
Supporting functionality spans several focused components:
- VPhoneScreenRecorder.swift – Frame capture and video encoding
- VPhoneLocationProvider.swift – macOS CoreLocation bridging to VM
- VPhoneProgressBar.swift – Visual feedback for long operations
Core Helpers (VPhoneCore)
The shared VPhoneCore library contains reusable infrastructure:
| Component | Responsibility |
|---|---|
VPhoneProcessRunner.swift |
Subprocess management |
VPhoneNetworking.swift |
URL session utilities |
VPhoneVerbosity.swift |
Structured logging |
VPhoneVMPicker.swift |
VM selection UI |
VPhoneFirmwareCatalog.swift |
Firmware metadata management |
These utilities serve both the Swift UI and command-line targets.
Execution Flow
Understanding how these layers interact clarifies the architecture's loose coupling:
- Bootstrap –
VPhoneCLIparses arguments, delegates toVPhoneAppDelegate - Configuration –
VPhoneVirtualMachineandVPhoneHardwareModelassembleVZVirtualMachineConfiguration - Launch – VM starts,
VPhoneVirtualMachineViewrenders display - Daemon startup –
vphonedinitializes inside iOS VM, listens on vsock port 1337 - Control connection –
VPhoneControlconnects, exposes high-level APIs - User interaction – Menus, keyboard shortcuts, and file browser operate through the control layer
- Firmware preparation – Optional patching runs pre-boot, producing CFW image
Code Examples
Launching a VM Programmatically
import VPhoneCLI
let options = VPhoneVirtualMachine.Options(
firmware: .regular,
cpuCount: 4,
memorySize: 4096 * 1024 * 1024
)
let vm = VPhoneVirtualMachine(options: options)
try await vm.start()
This creates the hardware model, configures the virtual machine, and begins execution.
Installing an IPA via the Control Interface
let installer = VPhoneIPAInstaller()
try installer.installIPA(
at: "/path/to/Application.ipa",
into: vm,
using: VPhoneControl()
)
The installer extracts, re-signs, and streams the payload through the vsock connection.
Retrieving Files from the Guest
let control = VPhoneControl()
let data = try await control.fetchFile(
at: "/var/mobile/Documents/config.plist"
)
VPhoneControl serializes the request as JSON, transmits over vsock, and returns raw bytes.
Summary
- vphone-cli architecture separates VM lifecycle, vsock communication, UI, and firmware patching into distinct layers
- Core VM layer wraps
VZVirtualMachinewithVPhoneVirtualMachine.swift,VPhoneHardwareModel.swift, and@MainActorsafety - Guest communication uses vsock port 1337 with
VPhoneControl.swiftimplementing length-prefixed JSON protocol - Menu system is extensible through
VPhoneMenuController.swiftregistration pattern - Firmware pipeline isolates Python patchers from Swift client via
VPhoneFWCLI.swift - IPA installation combines
VPhoneSigner.swiftMach-O signing withVPhoneIPAInstaller.swiftstreaming - All interactions flow through the control layer, never direct VM manipulation, ensuring testability and extension points
Frequently Asked Questions
What virtualization technology does vphone-cli use?
vphone-cli builds directly on Apple's Virtualization.framework, the native macOS hypervisor framework. The VPhoneVirtualMachine class in sources/vphone-cli/VPhoneVirtualMachine.swift wraps VZVirtualMachine and VZVirtualMachineConfiguration, using private APIs via the Dynamic library for hardware model selection.
How does vphone-cli communicate with the iOS VM?
Communication occurs over vsock (socket address family 40) on fixed port 1337. The host-side VPhoneControl.swift connects to the in-VM vphoned daemon using a length-prefixed JSON protocol. This enables file transfer, IPA installation, location sync, and remote command execution without network stack dependency.
Can vphone-cli run modified or jailbroken iOS firmware?
Yes. The FirmwarePatcher pipeline in sources/FirmwarePatcher/ provides Python-based tooling to modify kernels, device trees, and cryptex files. VPhoneFWCLI.swift exposes variant selection (regular, dev, jailbreak, experimental) and orchestrates patch application before VM boot, producing a custom CFW image consumed by the virtualization layer.
What is the role of VPhoneCore in the architecture?
VPhoneCore is a shared library containing reusable utilities used across the codebase: process spawning (VPhoneProcessRunner.swift), networking (VPhoneNetworking.swift), logging (VPhoneVerbosity.swift), and firmware catalog management (VPhoneFirmwareCatalog.swift). Both the SwiftUI application and command-line utilities depend on this layer, preventing code duplication between interfaces.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →