底层

iphone-use 怎么工作

每台手机在 Mac 上对应一个守护进程。它把屏幕读成无障碍树(文字,不是像素),通过装在 iPhone 上的小型 XCTest runner 发送点击和输入,并在画面稳定后才返回结果。agent 和人走的是同一个守护进程,同一时间只有一方在用手机。

架构
 Claude Code / Codex / 任何 MCP 客户端 ─MCP──┐
 脚本和其他 agent ─────────────────────HTTP──┤
                                             ▼
                          Mac 上的 iphone-use 守护进程 ──USB 或 Wi-Fi──▶ iPhone 上的 XCTest runner
                                             ▲
 你,用浏览器或 iOS App ─────────────────────┘

守护进程

守护进程以当前用户的 LaunchAgent 运行,监听 127.0.0.1:44321 并要求密码。它用三种形式提供同样的控制:给 agent 的 MCP server、给脚本的 /agent/* HTTP 接口,以及给人用的网页和 iOS 原生 App(见接入方式)。

XCTest 设备 runner

iphone-use 用自研的 XCTest UI 测试包(runner/)操作手机。它从 v0.14.0 起取代了 WebDriverAgent,接口与 WebDriverAgent 的 HTTP API 兼容,不使用 iPhone 镜像。它是为速度设计的:

iphone-use setup 用你的 Xcode 开发团队构建并签名 runner,在手机上启动它,再固定两条本机中继:8100 用于控制,9100 用于画面。中继走 macOS 自带的 usbmuxd(iphone-use relay),所以守护进程只跟 localhost 通信,也不需要 Homebrew 包。

USB 与 Wi-Fi

ℹ️ 维护者实测
来自完整指南:走 Wi-Fi 隧道一次点击约 330–380 毫秒,USB 约 280 毫秒。在 iPhone 17 Pro Max(iOS 27)上,解锁状态的冷连接 13–22 秒后可操作。在 iPhone X(iOS 16.5)上,一次重建 runner 的旧版路径配置用了 141 秒;iPhone 12 mini(iOS 15.4.1)热重启约 12 秒。

请求签名

手机上 runner 的端口会拒绝(401,不做任何事)没有用本次启动令牌签名的请求:签名是对方法、目标、正文、时间戳和一次性随机数做的 HMAC-SHA256。令牌只留在 Mac 上(权限 0600),从不发送,所以截获的请求既不能重放也不能篡改。没有令牌启动的 runner 拒绝一切请求。签名不等于加密,见隐私与安全。

生命周期:空闲释放与预热

把手机交还给人

实时画面:浏览器与 iOS App

/phone 页面显示实时画面:由手机上的 runner 编码的 H.264(浏览器不支持 WebCodecs 时用 MJPEG)。单击是点击,拖动是滑动,按住是长按,滚轮滚动,打字用你自己的输入法直接进手机。画面不变时不会重新编码。

模式画面静止画面滚动时
性能一半尺寸,最高 30 fps约 0.04 Mbit/s约 1.5 Mbit/s
画质原生尺寸(17 Pro Max 上 1320×2868),约 50 fps约 0.1 Mbit/s约 6 Mbit/s

自动模式在本机或同一局域网用画质模式,其他地方用性能模式。在禁止截屏的页面(银行、支付),你看到的是无障碍树的实时线框图,而不是一片空白,照样可以点着操作。

SwiftUI 原生 iOS App(最低部署版本 iOS 15)在 Mac 网页上扫码配对,用系统硬件解码播放 H.264 画面。它不在 App Store 上:iphone-use setup-app 会用你自己的签名团队构建它。

手机上的守护进程与本机控制

手机上的守护进程和 Mac 上是同一个程序,链接进了 runner。有付费开发者团队时,iOS App 里的 packet-tunnel 扩展会在手机本身上启动 runner,手机自己就能提供点击、输入、读屏和 agent 接口,运行时不需要 Mac(iOS 17.4 及以上;第一次配对仍需插一次 USB 线)。免费 Apple ID 得到的是远程 App,用来操作由 Mac 托管的手机。交给守护进程的 agent 任务在其他 App 处于前台时也会继续运行。

不止一台手机

一个守护进程操作一台手机。命名实例(./install.sh --instance lab --udid <UDID>)有自己的一份 App、状态目录、launchd 标签、令牌和端口,不动默认安装。每台手机有独立的守护进程和 runner,两台同时操作时,每台都和单独操作一样快。MCP 调用可以用 instance 参数逐次选择已安装的实例。

模拟器(预览)

runner 也能跑在 iOS 模拟器上,不需要手机、Apple ID 或签名:iphone-use simulator start "iPhone 16 Pro" 会编译并启动所需的一切,然后用 IPHONE_USE_INSTANCE=sim 把 MCP 客户端接上去。模拟器没有相机、App Store 应用、真实推送和 Face ID,需要这些的任务只能在真机上做。

速度

以下是项目自己的实测,来自 README(2026 年 10 月,同一台 iPhone 13,USB 连接):

iphone-use runneragent-device
读屏(无障碍树)0.08–0.135 秒约 0.7 秒
点击并等画面稳定1.0 秒2.8–3.3 秒

走完整的 agent 接口,在 iPhone 17 Pro Max 上按标签点击并带回稳定后的变化约 1.9 秒,基于 WebDriverAgent 的版本是 4.2 秒。实时画面 27–28 fps。这些是维护者的实测,不是第三方评测。

深入阅读:完整指南、设备 runner 和架构说明。