# How the Touch Injection Strategy Differs Between iOS 26.x and iOS 27.x in VPhoneControl

> Discover how VPhoneControl's touch injection strategy changes between iOS 26.x and iOS 27.x. Learn about guest-side vs. native VZ multitouch handling and kernel version differences.

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

---

**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/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

```swift
/// 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/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**: `VPhoneControl` actively logs activation of guest injection and routes all touch events through `vphoned` via the `sendTouch` method.
- **iOS 27.x**: The UI layer in [`VPhoneVirtualMachineView.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachineView.swift) creates native `VZMultiTouchEvent` instances, allowing the VM to handle multitouch through Apple's official virtualization APIs without additional daemon communication.

## Summary

- **Version Detection**: `useGuestTouchInjection` in [`VPhoneControl.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneControl.swift) checks if the guest kernel major version is less than 26 to identify iOS 18 systems.
- **iOS 26.x Behavior**: Requires guest-side injection via `vphoned` because the VZ USB touchscreen dext receives reports but emits no digitizer events.
- **iOS 27.x Behavior**: Uses native `VZMultiTouchEvent` processing through the Virtualization Framework, as the kernel properly handles USB touchscreen digitizer events.
- **Key Files**: [`VPhoneControl.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneControl.swift) contains the decision logic and `sendTouch` method, while [`VPhoneVirtualMachineView.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachineView.swift) handles 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`](https://github.com/Lakr233/vphone-cli/blob/main/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.