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:
- After rotating between landscape/portrait or changing resolution, re-call
setScreenSize, otherwise coordinates shift as a whole; - In landscape, just swap width and height — e.g. portrait is
setScreenSize(1170, 2532), landscape issetScreenSize(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
codeis0; on failurecodeis non-zero andmsgis 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,inputTextis 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
setClipboardthen 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?
typeTextis key-by-key and auto-switches to paste for non-English;inputTextalways 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.
getClipboardhas 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.