iOSUSB HIDAutomation Scripts

How to Write iOS Automation Scripts with USB HID: A No-Jailbreak, No-Signature, No-Hardware Full Tutorial

A hands-on guide to writing iOS automation scripts with USB HID: from opening a session and setting the screen size to full coverage of taps, swipes, text input, and multi-touch, with usbHidEvent code samples and coordinate conversion tips, then calling the same operations once from Python via the HTTP interface. Fully no-jailbreak, no-signature, no-hardware — a single cable gets Apple cluster control and automation scripts running.

8 min read

1. How Exactly Is USB HID Different From Older iOS Automation?

The core difference: the PC pretends to be a USB keyboard/mouse and sends commands directly — fully no-jailbreak, no-signature, no-hardware.

If you’ve done Android automation before, you might instinctively assume iOS needs jailbreak, signing, and a pile of hardware. But the USB HID route works on a completely different logic.

Its principle is: make the PC pretend to be a USB keyboard/mouse and feed clicks, swipes, and typing straight into the iPhone.

HID is a device class in the USB spec — keyboards and mice belong to it. Once the PC emulates a HID peripheral, the iPhone treats it as a real external device — the system can’t tell whether the signal came from a human finger or a program.

Because it doesn’t touch the system internals, therefore:

  • No jailbreak — the phone stays as-is;
  • No app install (in USB_HID mode), so no signing;
  • No Bluetooth board or OTG board — just one cable.

Let’s go from zero and walk through how to write the script.

2. What Should You Prepare Before Writing the Script?

Three things: install the central control, connect the phone and pick the right mode, and remember the return convention.

1. Environment

  • A computer running the central control (on Windows, install to a pure-English path);
  • An iPhone connected to the computer with a cable;
  • Confirm the phone has trusted this computer and the central-control bridge has started.

2. Pick the right mode

In the mirroring client’s System Settings → Scenario Mode, choose:

  • No Automation Screenshot + USB_HID — simplest, no app on the phone, plug in and use;
  • Main Program Screen Recording + USB_HID — needs the offline main-program IPA installed, in exchange for smoother visuals.

Both modes require the phone to be on iOS 17 or later.

3. Remember one return convention

All usbHidEvent functions share the same return rule: returning null or an empty string means success; returning any other string is an error message.

So when writing scripts, prepare a check function first — you’ll use it throughout:

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

3. How Do You Write the First Script, and in What Order?

Three steps control the iPhone: start the session, set the screen size, then tap and input — keep the order.

USB HID operations happen inside a “session.” The order is fixed: start the session first, then set the screen size, then taps and input.

function main() {
    // 1. Start session (true enables enhanced compatibility mode)
    let r = usbHidEvent.sessionStart(true);
    if (!_usbOk(r)) {
        logw("Failed to start USB HID: " + r);
        return;
    }

    // 2. Set screen size, using the actual screenshot/mirror resolution
    r = usbHidEvent.setScreenSize(1170, 2532);
    if (!_usbOk(r)) {
        logw("Failed to set screen size: " + r);
        return;
    }

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

    // 4. Final cleanup: release resources
    usbHidEvent.sessionStop();
}

main();

Once these three steps run, you’re already controlling the iPhone. Everything after is just adding more actions onto this skeleton.

The three session operations

Function Purpose When to use
sessionStart(gate) Start a session At the start of the script; reuses an existing session if present
sessionRestart(gate) Rebuild the session When touch fails, the stream drops, or taps do nothing
sessionStop() Close the session At script end, to release resources

sessionRestart is effectively stop then start — more thorough than calling sessionStart once more — because sessionStart may reuse the old connection, while restart forcibly tears down and rebuilds.

4. What Are the Common USB HID Functions?

Common functions split into three groups: touch, input, and system keys — covering taps, swipes, typing, and volume.

Touch

Function Description
clickPoint(x, y) Single tap
doubleClickPoint(x, y) Double tap
press(x, y, delay) Long press; delay is the hold time in milliseconds
swipeToPoint(sx, sy, ex, ey, duration) Swipe from start to end; duration is the time in milliseconds
touchDown(x, y) / touchMove(x, y) / touchUp(x, y) Down / move / up, for fine-grained three-phase control
multiTouch(touch1, timeout) Multi-finger trajectory replay, good for complex gestures

multiTouch trajectory point format: action of 0 means down, 2 means move, 1 means up, 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) Keyboard key-by-key input; auto-switches to paste for Chinese, emoji, etc.
inputText(text) Always clipboard paste; works for both Chinese and English
setClipboard(text) Only writes to the clipboard, no paste
keyPressChar(prefix, code) Character or combo key, e.g. ("gui", "v") means paste
keyPress(key) / keyUp() Press a single key / release all keys

System and others

Function Description
systemKey(key) home home screen / recents multitasking / lock lock screen
volumeUp() / volumeDown() / mute() Volume and mute
setScreenSize(w, h) Set screen pixel width/height, which determines all later coordinate conversion

5. How Do You Write Coordinates So You Don’t Tap Off-Target?

One rule: set the screen size first, then write all coordinates against screenshot pixels — WYSIWYG.

This is the pitfall beginners hit most often, but the rule is just one sentence:

First use setScreenSize to set the device pixel width and height; after that, write all coordinates against the screenshot pixels.

That is, if a button is at (200, 400) in your screenshot, you write clickPoint(200, 400) in the script — WYSIWYG.

Two things to note:

  1. After rotating between landscape/portrait or changing resolution, re-call setScreenSize, otherwise coordinates shift as a whole;
  2. In landscape, just swap width and height — e.g. portrait is setScreenSize(1170, 2532), landscape is setScreenSize(2532, 1170).

6. If You Don’t Use EC Scripts, Can Python Call USB HID?

Yes. The central control exposes an HTTP interface — POST + JSON, mapping one-to-one to the script functions, callable from Python.

Don’t want to use EC scripts, or your main program is written in Python / C# / EasyLanguage? No problem. The central control exposes an HTTP interface, mapping one-to-one to the script functions.

  • Path prefix: the central-control address, e.g. http://127.0.0.1:8019
  • All POST, Content-Type: application/json
  • On success code is 0; on failure code is non-zero and msg is the error message

For example, a tap from Python:

import requests

body = {
    "deviceId": "your-device-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

Recommended order: call usbhidSessionStart first, then usbhidSetScreenSize, then taps and input — consistent with the order in the script.

7. What Pitfalls Do Beginners Hit With USB HID Scripts?

Most common: forgetting to set the screen size, giving up when a tap does nothing, wrong input function, relying on getClipboard.

  • Forgot to set the screen size first: tapping directly, all positions off. Build the habit of “setScreenSize right after the session”;
  • Gave up when a tap did nothing: usually a session-state issue; right-click the device and choose “USB HID → Rebuild USBHID Session” usually fixes it, faster than re-running the whole script;
  • Used the wrong input function: wanted Chinese but used typeText — actually it auto-switches to paste and still works; but if you know it’s Chinese, inputText is more direct;
  • Extra spaces when pasting English: turn off “Smart Punctuation” under Settings → General → Keyboard on the phone;
  • Relying on getClipboard to read content: this interface is unstable on some iOS versions and may time out reading what a human long-pressed to copy; write with setClipboard then read, or pass text another way;
  • Assumed plugging in the cable lets you tap: you also need the phone to have trusted this computer and the central-control bridge started, otherwise the session can’t even open.

8. What Other Frequent Questions Are There About USB HID Scripts?

The FAQ below covers app install, coding barrier, sync vs async, coordinates, and Python calling.

  • Q: Need to install an app? No. In “No Automation Screenshot + USB_HID” mode nothing is installed on the phone, plug in and use, and no signing or certificate renewal is involved.
  • Q: Usable without coding? Yes. The new central control has a built-in AI agent — just give instructions in plain language; you can also orchestrate with the visual workflow editor.
  • Q: Are the functions sync or async? Write them as synchronous; a null or empty return means success, any other string is an error message.
  • Q: What coordinate values are correct? First setScreenSize to the pixel width/height, then write against screenshot pixels — WYSIWYG.
  • Q: Difference between English and Chinese input? typeText is key-by-key and auto-switches to paste for non-English; inputText always uses paste.
  • Q: Can Python call it? Yes. Via the HTTP interface, POST http://<control-IP>:8019/openapi/usbhid*, mapping one-to-one to the script functions.
  • Q: Tap does nothing — what now? Check connection and trust status, verify screen size, then try “Rebuild USBHID Session”.
  • Q: What can’t it do? Excels at operation-layer actions; reading screen content needs the screenshot interface. getClipboard has known instability on some iOS versions.

Related reading: For a systematic look at the overall no-jailbreak iPhone automation solution, see The Complete Guide to No-Jailbreak iPhone Automation Scripts.


About EasyClick: A phone automation AI-agent platform covering Android no-root, iOS no-jailbreak (proxy / Bluetooth HID / OTG HID) and HarmonyOS Next, offering script development, Apple cluster control, local central control & mirroring, and cloud control systems. → 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 →