Remote XPC Tunnels
The XCUITest driver can use Remote XPC (via appium-ios-remotexpc) and an IPv6 tunnel to talk to
real iOS and tvOS devices on OS version 18 or newer. This guide explains how to:
- Create and inspect tunnels using the
tunnel-creationscript - Run tests against real devices using those tunnels
- Plan parallel test runs when using a single Appium server or multiple servers
This guide applies to real iOS/tvOS devices only. Simulators do not use this tunnel mechanism.
At the moment, the tunnel workflow described here supports devices physically connected via USB to the host running Appium. Support for wireless tvOS / Apple TV devices via Remote XPC tunnels is planned but not yet available in this driver.
When you need tunnels and 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 uses:
appium-ios-remotexpcfor:- Device lockdown / USBMUX communication
- CoreDeviceProxy and Remote XPC connections
- High‑level services (installation proxy, AFC, crash reports, DVT instruments, etc.)
appium-ios-tuntap(used internally byappium-ios-remotexpc) to:- Create a TUN/TAP virtual network interface
- Establish an IPv6 tunnel between the host and the device
For iOS/tvOS < 18 these tunnels are not required and the driver falls back to legacy transport.
Prerequisites¶
- Host OS:
- macOS or Linux (tunnels rely on TUN/TAP support)
- Node.js / Appium:
- Node.js compatible with this driver version (see
package.jsonor README) - Appium 3.x
- Node.js compatible with this driver version (see
- Device setup:
- Real iOS or tvOS device on 18.x or newer
- Device paired and trusted on the host
- Developer tools and Xcode installed (for general iOS development and pairing)
-
Optional dependency (required for tunnels):
- The driver declares
appium-ios-remotexpcas 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. - For details about Remote XPC and IPv6 tunneling, see the
appium-ios-remotexpcREADME.
- The driver declares
-
Privileges:
- sudo/root is required to create TUN/TAP interfaces for the tunnel. You should generally run
the tunnel script with
sudo(or an equivalent mechanism, such as a root container).
- sudo/root is required to create TUN/TAP interfaces for the tunnel. You should generally run
the tunnel script with
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 with the driver script¶
The XCUITest driver exposes a high‑level convenience script that wraps the lower‑level
appium-ios-remotexpc tunnel workflow:
This script:
- Connects to
usbmuxdand enumerates all connected, trusted iOS/tvOS devices - 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
Command-line options¶
The script supports a few options:
-
Target a specific device:
-
Customize packet stream base port:
The script will assign
52000,52001,52002, … to packet stream servers for each device. -
Customize tunnel registry port:
The registry API will then be available at:
http://localhost:43000/remotexpc/tunnels
The script also stores the chosen port in a strongbox entry for the
appium-xcuitest-driverpackage so that driver instances can locate the registry automatically.
Inspecting the tunnel registry¶
After a successful run 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
...
curl http://localhost:<port>/remotexpc/tunnels/<udid>
Useful endpoints:
-
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 on a single Appium server¶
Once tunnels are running, you can start a standard Appium server with the XCUITest driver and run tests against iOS/tvOS 18+ real devices using normal capabilities.
Recommended workflow¶
-
Start the tunnels (once per host):
Leave this process running in the background while tests execute.
-
Start the Appium server (in a separate terminal):
-
Run your tests using standard XCUITest capabilities:
{ "platformName": "iOS", "appium:automationName": "XCUITest", "appium:platformVersion": "18.4", "appium:udid": "<device-udid>", }For tvOS, set
"platformName": "tvOS"and use the UDID of your Apple TV device. -
How the driver uses tunnels:
- When
platformVersionis 18 or higher on a real device, the driver:- Automatically imports
appium-ios-remotexpc(viagetRemoteXPCServices) - Uses Remote XPC services (installation proxy, AFC, diagnostics, DVT instruments, etc.) instead of the legacy paths
- Relies on the IPv6 tunnels created by the tunnel registry for connectivity
- Automatically imports
- If
appium-ios-remotexpcis missing or tunnels are not available, some advanced real‑device features for 18+ may be unavailable or will fall back to slower/less reliable code paths.
- When
No extra capabilities are required to “enable” tunnels; they are automatically used when:
appium-ios-remotexpcis installed, and- the tunnel registry server is reachable, and
- the platform is iOS/tvOS 18+ on a real device.
Parallel tests with a single Appium server¶
The tunnel creation script is multi‑device aware: it creates and registers an independent tunnel for each connected device. XCUITest 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
Example: single server, multiple devices¶
-
Create tunnels for all connected devices:
-
Start one Appium server:
-
Run tests in parallel, for example:
-
Session A:
-
Session B:
-
-
Driver behavior:
- Each session uses the UDID to pick the appropriate tunnel from the registry.
- Underneath,
TunnelManagermaintains a registry of active tunnels and Remote XPC connections keyed by tunnel address and reuses them when possible. - Packet stream servers created by the tunnel script are already bound to distinct TCP ports, so traffic for different devices is isolated.
Guidelines for single‑server parallelism¶
- Do not share a UDID across concurrent sessions on the same server; use one session per device.
- Ensure the tunnel script is running before starting parallel tests so that the registry is populated.
- If you frequently add/remove devices, re‑run the tunnel script to refresh the registry.
Parallel tests with multiple Appium servers¶
You can also run multiple Appium servers in parallel on the same host while sharing a single tunnel registry and tunnel process.
Recommended pattern: one tunnel process, many servers¶
-
Start a single global tunnel process:
- Leave this running in the background.
- It creates tunnels for all currently connected devices and exposes the registry on
43000. - The registry port is persisted in a strongbox entry for
appium-xcuitest-driverso that all driver instances running in the same environment can discover it.
-
Start multiple Appium servers, for example:
-
Assign devices to servers via capabilities:
- Server 1 handles device A (iOS 18.x, UDID
<iphone-udid>) - Server 2 handles device B (tvOS 18.x, UDID
<appletv-udid>)
- Server 1 handles device A (iOS 18.x, UDID
-
Run tests in parallel across servers:
- Each server behaves as described in the single‑server section, using the shared tunnel registry.
- Tunnels are created only once; both servers reuse the same IPv6 tunnel and Remote XPC infrastructure for each device.
Alternative: one tunnel process per isolation boundary¶
In more advanced setups (e.g., Docker, multiple hosts, CI agents), you might:
- Run one tunnel‑creation process per container/VM, started together with that container’s Appium server(s).
- Use distinct
--tunnel-registry-portvalues 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 USBMUX connections.
Guidelines for multi‑server parallelism¶
- Prefer a single global tunnel process per physical host and share it between servers.
- Ensure all Appium servers that should share tunnels:
- Run under the same user or environment where the strongbox entry is accessible, or
- Are configured to discover the same tunnel registry port (by starting the script with an
explicit
--tunnel-registry-port).
- As with a single server, never assign the same UDID to multiple concurrent sessions unless your test coordination knows exactly what it is doing.
tvOS‑specific notes¶
- The tunnel creation and Remote XPC mechanism works the same way for tvOS 18+ as for iOS 18+.
- Use:
"platformName": "tvOS"- A tvOS 18+
platformVersion - The UDID of the Apple TV device
- Only devices connected via USB are currently supported. Support for wirelessly connected TV devices is coming.