Remote XPC Tunnels
Certain features of the XCUITest driver rely on Remote XPC services and IPv6 tunneling. This
functionality is provided by the optional appium-ios-remotexpc
library.
Info
The driver only uses remote XPC tunnels for real devices running iOS/tvOS 18 or later. Real devices running iOS/tvOS < 18 do not support this tunneling mechanism, whereas simulators do not need to use it.
Why Use Remote XPC¶
On iOS/tvOS 18+, Apple routes many system services (including XCTest-related ones) over IPv6-only interfaces and Remote XPC endpoints. The XCUITest driver utilizes them for the following features (non-exhaustive list):
- General communication with wireless Apple TV devices
- Retrieval of various logs
- Network monitoring
- Certificate management
- Execution of native XCTest test suites
Prerequisites¶
- macOS or Linux host
- Real device running iOS/tvOS 18 or later, paired and trusted on its host
- The driver supports devices connected via
usbmuxd(wired and wireless), as well as wireless tvOS devices (must be paired first, see tvOS guide)
- The driver supports devices connected via
appium-ios-remotexpcinstalled- The driver declares this package as an optional dependency, so in a normal installation npm will install it automatically. You only need to install it manually if the optional dependency step failed or you are wiring a custom environment.
To verify that the optional dependency and tunnel infrastructure are available, you can run:
Look for the optional checks related to appium-ios-remotexpc and “tunnel availability”.
Creating Tunnels¶
The XCUITest driver exposes a high‑level convenience script that wraps the lower‑level
appium-ios-remotexpc tunnel workflow.
Warning
This script must be run as sudo/root to create TUN/TAP interfaces for the tunnel.
Refer to the script reference page for a list of additional options.
The script executes the following actions:
- Enumerates all connected and trusted iOS/tvOS devices
- The list of available devices can also be retrieved using the
list-real-devicesscript
- The list of available devices can also be retrieved using the
- For each device:
- Starts a Lockdown session
- Starts
com.apple.internal.devicecompute.CoreDeviceProxyvia Remote XPC - Creates an IPv6 tunnel using
TunnelManager.getTunnel(...) - Starts a packet stream server on a local TCP port (default base:
50000)
- Builds an in‑memory tunnel registry containing:
- Device UDID and device ID
- Tunnel IPv6 address (
Address) andRsdPort - Packet stream port and basic metadata
- Starts an HTTP tunnel registry API server and prints its address
- Persists the chosen registry port in a per‑driver strongbox entry so that the driver can find it
Inspecting the Tunnel Registry¶
After a successful script execution, you should see log lines similar to:
📁 Tunnel registry API:
The tunnel registry is now available through the API at:
http://localhost:<port>/remotexpc/tunnels
You can now use the registry endpoints to retrieve tunnel information:
-
List all tunnels:
-
Get tunnel for a specific UDID:
The response contains the IPv6 address, rsdPort, and other metadata required to establish
Remote XPC connections.
Running Tests¶
Make sure to create all required tunnel(s) before launching your tests. The tunnel process(es) should remaing running in the background, in addition to the Appium server process.
No extra capabilities are required to "enable" tunnels; they are automatically used when:
appium-ios-remotexpcis installed- the tunnel registry server is reachable
- the platform is a real device running iOS/tvOS 18 or later
Multiple Sessions¶
The tunnel creation script is multi‑device aware: it creates and registers an independent tunnel
for each connected device. It can also be limited to specific devices by passing --udid/--appletv-device-id
multiple times. The driver can then run multiple sessions concurrently on a single Appium server
as long as:
- Each session uses a different real device (
appium:udidis unique per session) - The tunnels for all those devices are present in the tunnel registry
If you frequently add/remove devices, consider occasionally re‑running the tunnel script to refresh
the registry, or use the --disconnect-retry-max-attempts/--disconnect-retry-interval-ms options
to configure automatic reconnection.
Multiple Appium Servers¶
Since the tunnel registry server is running in a separate process, it is not linked to a specific Appium server instance, and can be used by multiple Appium servers simultaneously. To ensure that all Appium server instances discover the same tunnel registry, you can set a specific port:
Similarly to running multiple sessions on a single server, make sure that each session uses a different device UDID.
In more advanced setups (e.g., Docker, multiple hosts, CI agents), you may want to run one
tunnel‑creation process per container/VM. In such cases, use distinct --tunnel-registry-port
values for each isolation boundary. This keeps tunnel state scoped to each environment, but within
that boundary you should still avoid running multiple competing tunnel‑creation scripts
simultaneously, as they may fight over TUN/TAP configuration and usbmuxd connections.