iOSUSB HIDautomation scripts

How Do You Write an iOS Script with USB HID? A Full Tutorial with No Jailbreak, No Signature, and No Hardware

Run Apple cluster control on one data cable, with no jailbreak, no signature, and no hardware: from opening a session and setting the screen size, through taps, swipes, text input, and multi-touch, with code samples and coordinate conversion.

7 min read

An automation script turns repeated manual operations on a phone into a program. Cluster control adds centralized management of many devices on top of that. The sections below cover how to write a script on the USB HID path.

How USB HID differs from other iOS automation

USB HID is available from EC iOS USB 10.7.0 (2026-09-08). The computer pretends to be a USB keyboard and mouse over the data cable, and sends taps, swipes, and typing to the iPhone. HID is a device class in the USB specification, and keyboards and mice both belong to it. The phone treats it as an external device. The system stays unchanged, so there is no jailbreak. In “no-automation screenshot + USB_HID” mode there is no app to install, so there is no IPA to sign, and no Bluetooth board or OTG board.

It is mutually exclusive with the proxy automation service. “Start automation” in the central control, startEnv in a script, and usbHidEvent are one path or the other. Do not mix them on the same device or in the same script. When you need a screenshot, use image.captureFullScreenNoAuto. The phone system is iOS 17 or later. If iOS 15 or later needs a program installed to run automation, use offline main program v7.2.0 or later as the USB automation program, and the official download page has a pre-signed IPA for testing. The offline main program goes through the automation service, and it is mutually exclusive with usbHidEvent. The offline build supports only iOS 15 or later.

EasyClick mirroring main screen showing live views of many devices

Before you start, install the central control, connect the phone, pick the right mode, and remember the return convention. The computer runs the central control, and the Windows install path uses plain English. Connect the iPhone to the computer with a data cable, confirm it has trusted this computer, and confirm the central-control bridge has started. In the mirroring client’s system settings, under scenario mode, choose “no-automation screenshot + USB_HID” (no app on the phone), or “main-program screen recording + USB_HID” (the offline main-program IPA has to be installed, and the picture is smoother). Both require iOS 17 or later. Below that version, switch to proxy mode. Proxy mode needs a signature: an individual developer account is 688 yuan a year, up to 100 devices, supporting iOS 12 or later. TrollStore supports iOS 15 through 16.6.1, and a reboot drops the signature. From 7.0.0, single-app installs only the main program, and dual-app also installs the proxy IPA.

USB HID mirroring preset settings

There is one return convention: every usbHidEvent function returns null or an empty string on success, and any other string is an error message. Put a check function in place before you write the script, and keep using it.

function _usbOk(r) {
    return r == null || r === "";
}

From opening a session to the functions you use

USB HID operations happen inside a session. The order is fixed: open the session, then set the screen size, and only then tap and type. Reverse the order and the coordinates and taps that follow will not line up.

function main() {
    // 1. Open the session (true enables enhanced compatibility mode)
    let r = usbHidEvent.sessionStart(true);
    if (!_usbOk(r)) {
        logw("开启 USB HID 失败: " + r);
        return;
    }

    // 2. Set the screen size to the actual screenshot or mirroring resolution
    r = usbHidEvent.setScreenSize(1170, 2532);
    if (!_usbOk(r)) {
        logw("设置屏幕尺寸失败: " + r);
        return;
    }

    // 3. Tap
    r = usbHidEvent.clickPoint(200, 400);
    logd("点击: " + (_usbOk(r) ? "成功" : r));

    // 4. Finish, and release resources
    usbHidEvent.sessionStop();
}

main();

After those three steps run through, add actions on top. A session has three operations:

Function Use When to use it
sessionStart(gate) Open a session At the start of the script; an existing session is reused
sessionRestart(gate) Rebuild the session When touch fails, the stream drops, or a tap does nothing
sessionStop() Close the session Release resources at the end of the script

sessionRestart is a stop followed by a start. sessionStart may reuse the old connection. sessionRestart disconnects and builds it again.

The common functions fall into touch, input, and system. Touch:

Function Description
clickPoint(x, y) Single tap
doubleClickPoint(x, y) Double tap
press(x, y, delay) Long press. delay is how many milliseconds to hold
swipeToPoint(sx, sy, ex, ey, duration) Swipe from the start point to the end point. duration is the length in milliseconds
touchDown(x, y) / touchMove(x, y) / touchUp(x, y) Press / move / lift, for a three-part operation that needs fine control
multiTouch(touch1, timeout) Replay a multi-point path, for a complex gesture

The point format for multiTouch: action of 0 means press, 2 means move, 1 means lift, and delay is that point’s delay in milliseconds.

let touch1 = [
    {"action": 0, "x": 100, "y": 500, "delay": 20},
    {"action": 2, "x": 100, "y": 300, "delay": 30},
    {"action": 1, "x": 100, "y": 300, "delay": 20}
];
usbHidEvent.multiTouch(touch1, 10000);

Input:

Function Description
typeText(text) Type key by key; Chinese and emoji switch to paste on their own
inputText(text) Always a clipboard paste, for both Chinese and English
setClipboard(text) Write the clipboard only, with no paste
keyPressChar(prefix, code) A character key or a combo, such as ("gui", "v") for paste
keyPress(key) / keyUp() Press a single key / lift every key

System and the rest:

Function Description
systemKey(key) home Home Screen / recents app switcher / lock lock screen
volumeUp() / volumeDown() / mute() Volume and mute
setScreenSize(w, h) Set the screen width and height in pixels, which decides the conversion of every later coordinate

For coordinates, call setScreenSize first, using the device’s pixel width and height. After that, every coordinate is written in the screenshot’s pixels. If a button is at (200, 400) in the screenshot, the script writes clickPoint(200, 400). After a landscape or portrait switch, or a resolution change, set it again, or the coordinates shift as a whole. Portrait is setScreenSize(1170, 2532). Landscape is written as setScreenSize(2532, 1170).

Python calls, common pitfalls, and answers

If the main program is Python, C#, or EasyLanguage, it can go through the central control’s HTTP interface. The paths match the script functions. The prefix is the central-control address, for example http://127.0.0.1:8019. Every call is POST with Content-Type: application/json. On success, code is 0. On failure, code is non-zero, and msg is the error message. Tap the screen once with Python:

import requests

body = {
    "deviceId": "你的设备 ID",
    "x": 200,
    "y": 400
}
r = requests.post("http://127.0.0.1:8019/openapi/usbhidClickPoint", json=body, timeout=30)
print(r.json())

The mapping is straightforward:

Script function HTTP interface
sessionStart /openapi/usbhidSessionStart
setScreenSize /openapi/usbhidSetScreenSize
clickPoint /openapi/usbhidClickPoint
press /openapi/usbhidPress
swipeToPoint /openapi/usbhidSwipeToPoint
typeText / inputText /openapi/usbhidTypeText / /openapi/usbhidInputText
systemKey /openapi/usbhidSystemKey

The recommended order is usbhidSessionStart first, then usbhidSetScreenSize, and only then taps and input, matching the order in the script.

Central control device grouping and bulk management

Check common problems in this order. Forget to set the screen size first, and the tap position drifts, so call setScreenSize as soon as the session is open. A tap that does nothing: right-click the device and choose “USB HID → Rebuild USBHID Session.” For Chinese, use inputText directly. Extra spaces when pasting English: on the phone, under Settings → General → Keyboard, turn off “Smart Punctuation.” getClipboard is unstable on some iOS versions. When you need to write, use setClipboard. After the cable is in, also confirm the phone has trusted this computer and the central-control bridge has started, or the session will not open.

From 10.6.0 (2026-09-02), the AI agent is iEasyRun, at https://ieasyrun.com . When you do not write EC scripts, you can arrange the work with chat or a workflow in the workstation. Write usbHidEvent as a synchronous call. null or an empty string is success. Reading the screen goes through the screenshot interface, and it does not go through screen mirroring.


Related reading: For the overall approach to no-jailbreak iPhone automation, see the complete tutorial on no-jailbreak iPhone automation scripts.

About EasyClick: A mobile automation script development platform covering three phone ecosystems: Android without root, iOS without jailbreak, and HarmonyOS. It also offers Apple script writing, Apple cluster control, Android cluster control, remote cloud control, and AI phone cluster control. → Explore all products

Ready to build it for real?

Every approach in this article can be built with EasyClick capabilities on iEasyClick — full documentation, developer tools and automation products, free to try.

Visit iEasyClick →