How the Touch Injection Strategy Differs Between iOS 26.x and iOS 27.x in VPhoneControl
VPhoneControl selects between guest-side touch injection and native Virtualization Framework (VZ) multitouch handling based on the guest kernel version. iOS 26.x (iOS 18 bases) requires forwarding touch events to the vphoned daemon because the VZ USB touchscreen dext fails to emit digitizer events, while iOS 27.x (iOS 19 bases) uses the native VZ multitouch path since the kernel correctly propagates touch data.
The Lakr233/vphone-cli repository implements a version-aware touch handling mechanism that adapts to changes in Apple's Virtualization Framework across iOS generations. By inspecting the guest kernel version at runtime, VPhoneControl determines whether to inject HID reports via the vphoned guest daemon or rely on the host's native multitouch pipeline. This conditional strategy ensures responsive touch input regardless of whether the virtualized instance runs iOS 18 or iOS 19.
Kernel Version Detection in VPhoneControl.swift
The decision logic resides in [VPhoneControl.swift](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneControl.swift), where the useGuestTouchInjection computed property evaluates the connected guest's capabilities and kernel version.
The useGuestTouchInjection Property
/// Whether touches should be injected guest‑side via vphoned rather than the
/// VZ USB touchscreen. True for iOS 18 bases: on the 26.x kernel their USB
/// touchscreen dext receives reports but emits no digitizer events, so the
/// UI never sees touches. 26.x bases keep the native VZ multitouch path.
var useGuestTouchInjection: Bool {
guard isConnected,
guestCaps.contains("touch"),
let major = guestIOSVersion.flatMap({ Int($0.split(separator: ".").first ?? "") })
else { return false }
return major < 26 // < 26 = iOS 18 (kernel 26.x)
}
This Boolean property returns true only when the guest reports a kernel version below 26, indicating iOS 18 (kernel 26.x) systems that lack functional digitizer event generation in the VZ USB subsystem.
iOS 26.x Guest-Side Injection Strategy
For iOS 26.x guests (iOS 18 bases), useGuestTouchInjection returns true, enabling the guest-side injection pathway. In this mode, the host captures touch events and forwards them to the vphoned daemon running inside the virtual machine.
The USB touchscreen dext in the VZ framework receives HID reports on these kernel versions but fails to generate corresponding digitizer events. Consequently, the UI layer inside the VM never registers touch input. To bypass this limitation, VPhoneControl transmits touch data using the sendTouch(phase:x:y:) method, which constructs a touch message type for the guest-side daemon to process as HID input.
iOS 27.x Native VZ Multitouch Handling
For iOS 27.x guests (iOS 19 bases), the property returns false, disabling guest-side injection. Touch events travel through the native VZ multitouch path implemented in [VPhoneVirtualMachineView.swift](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVirtualMachineView.swift).
The iOS 27.x kernel correctly propagates digitizer events from the USB touchscreen dext, eliminating the need for host-side intervention. When useGuestTouchInjection is disabled, the view controller creates VZMultiTouchEvent objects that the Virtualization Framework processes directly, delivering touch input to the guest OS through the standard VZ pipeline.
Implementation Comparison
- iOS 26.x:
VPhoneControlactively logs activation of guest injection and routes all touch events throughvphonedvia thesendTouchmethod. - iOS 27.x: The UI layer in
VPhoneVirtualMachineView.swiftcreates nativeVZMultiTouchEventinstances, allowing the VM to handle multitouch through Apple's official virtualization APIs without additional daemon communication.
Summary
- Version Detection:
useGuestTouchInjectioninVPhoneControl.swiftchecks if the guest kernel major version is less than 26 to identify iOS 18 systems. - iOS 26.x Behavior: Requires guest-side injection via
vphonedbecause the VZ USB touchscreen dext receives reports but emits no digitizer events. - iOS 27.x Behavior: Uses native
VZMultiTouchEventprocessing through the Virtualization Framework, as the kernel properly handles USB touchscreen digitizer events. - Key Files:
VPhoneControl.swiftcontains the decision logic andsendTouchmethod, whileVPhoneVirtualMachineView.swifthandles the alternative native path.
Frequently Asked Questions
Why does iOS 26.x require guest-side touch injection?
The VZ USB touchscreen dext on iOS 26.x (iOS 18 bases) receives HID reports but does not generate digitizer events, so the UI inside the VM never sees touches. Forwarding events through vphoned using the sendTouch method restores proper touch behavior by injecting HID data directly into the guest.
How does VPhoneControl detect which iOS version is running?
The useGuestTouchInjection property parses guestIOSVersion to extract the major kernel version number. It returns true for versions below 26 (indicating iOS 18) and false for version 26 and above (indicating iOS 19), while also verifying the connection status and that the touch capability is present in guestCaps.
What method transmits touch data to the guest daemon?
The sendTouch(phase:x:y:) method in VPhoneControl.swift packages touch events with phase, x-coordinate, and y-coordinate parameters into a touch message type, then transmits this data to the vphoned daemon running inside the virtual machine.
Does the touch injection strategy affect input latency?
Guest-side injection through vphoned adds a communication step between host and guest, whereas iOS 27.x uses the native VZ multitouch path with VZMultiTouchEvent objects that process directly within the Virtualization Framework, typically resulting in lower latency for newer iOS versions.
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 →