Baguette serve 路由参考:以 HTTP/WS API 编程式驱动 iOS 模拟器的完整清单
【免费下载链接】baguetteHeadless control for Apple's Simulators — 3D models, taps, swipes, multi-finger gestures, 60 fps streaming, and a multi-device farm项目地址: https://gitcode.com/gh_mirrors/baguette/baguette
Baguette是面向 Apple iOS 模拟器的 Headless 控制工具,而baguette serve内置了一个开箱即用的 HTTP + WebSocket 服务器:一条命令启动后,你就可以通过 30 多条 REST 路由和 6 条 WS 通道,编程式完成模拟器启动/关机、点击滑动等多指手势、60 fps 实时视频流、截图、3D 渲染、GPS/运动/网络注入等操作。本文是一份完整的 serve 路由参考清单,帮助你快速用脚本、CI 流水线或自己的网页驱动 iOS 模拟器。
快速启动模拟器控制服务器
默认监听http://127.0.0.1:8421,启动后浏览器打开根路径即可看到设备列表页:
baguette serve # http://127.0.0.1:8421/simulators常用参数(完整说明见 docs/commands.md):
| 参数 | 默认值 | 说明 |
|---|---|---|
--port | 8421 | 监听端口 |
--host | 127.0.0.1 | 绑定的网卡 / 主机 |
--allowed-hosts | 无 | 额外信任的 Host/Origin,可重复,*.example.com匹配子域 |
--plugin-dir | 无 | 额外插件目录,同名时遮蔽已装插件 |
--no-plugins | 关 | 忽略所有已安装插件 |
参数解析实现见 ServeCommand.swift。
路由设计三原则:UDID 在路径,格式看扩展名
📐 Baguette serve 的路由刻意做成了"一棵资源树",没有任何/api/前缀,规则非常直白:
- UDID 永远在路径里:
/simulators/:udid/…,一台设备就是一个命名空间; - 格式由文件扩展名决定:
screenshot.jpg给 JPEG、screenshot.png给 PNG、simulators.json给 JSON; - 薄处理器,无模板:服务器只把领域值投影成 JSON / PNG,UI 全部由 Resources/Web/ 下的静态 HTML/JS 承担。
设备生命周期路由:开机、关机、列设备
| 方法 | 路径 | 作用 |
|---|---|---|
GET | /simulators | 设备列表页(含 Boot / Shutdown 按钮) |
GET | /simulators.json | {running, available},与baguette list --json相同 |
POST | /simulators/:udid/boot | 启动模拟器 |
POST | /simulators/:udid/shutdown | 关机 |
一个典型的 CI 脚本序列就是GET /simulators.json找设备 →POST …/boot→ 测试 →POST …/shutdown。
手势输入路由:POST 一个 JSON 信封即可
POST /simulators/:udid/input是编程式驱动模拟器的核心路由:请求体放一个手势信封(JSON),响应体返回 ack。信封协议与baguette input共享,完整定义见 docs/wire.md。
支持的手势类型一览:
| type | 用途 | 关键点 |
|---|---|---|
tap | 单击 | 必填width/height,edge可触发 Home Indicator 等系统手势 |
swipe | 滑动 | 服务端插值,duration默认 0.25s |
touch1-down/move/up | 单指流式触摸 | 拖动、Home/App Switcher 拖拽、下拉通知中心 |
touch2-down/move/up | 双指流式触摸 | 实时捏合、旋转、双指平移 |
pinch/pan | 一次性捏合 / 双指平移 | 服务端自动插值 10 步 |
scroll | 滚轮滚动 | deltaY为负即内容上移 |
button | 实体按键 | home、lock、volume-up、action等 |
key/type | 按键 / 输入文本 | W3C 键码;仅 US-ASCII,其余请用paste |
三个最容易踩的坑:
- ✅ 坐标是设备点(points)不是像素,3× 屏用像素会偏 3 倍;
- ✅
width/height取自describe-ui的screen.width/height(每台设备不同,438×954 只是 iPhone 17 Pro Max); - ✅ 返回
{"ok":true}只代表已发送,不代表屏幕有反应。
60 fps 流式路由:一个 WebSocket 扛下整个会话
WS /simulators/:udid/stream?format=mjpeg|avcc是全双工的"整场观看会话":
- 服务器 → 页面:每条二进制消息一帧编码画面。MJPEG 直接发 JPEG 字节;AVCC(H.264)用 1 字节标签:
0x01avcC 描述、0x02关键帧、0x03增量帧、0x04JPEG 种子帧; - 页面 → 服务器:文本 JSON,包括流控制
set_bitrate/set_fps/set_scale/force_idr/snapshot与手势信封,二者共用同一通道。
没有旁路事件路由,也没有按 UDID 的注册表——socket 打开多久,流就持续多久;断开即停止采集。同族路由:
| 通道 | 用途 |
|---|---|
WS …/stream.3d.mjpeg/.avcc | 3D 舞台实时流(可set_3d_camera旋转设备模型) |
WS …/logs?level=&predicate=&bundleId= | 实时统一日志(unified log) |
WS …/camera | 虚拟摄像头控制(camera_start/camera_stop等) |
截图与 UI 结构路由:单帧画面 + 无障碍树
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /simulators/:udid/screenshot.jpg/.png | 单帧截图,支持quality、scale、size、fit、background查询参数 |
GET | /simulators/:udid/screenshot-bezel.png | 画面嵌在设备边框里的合成图(buttons=控制按键) |
GET | /simulators/:udid/describe-ui.json?x=&y= | 无障碍树;带x+y时对该点做命中测试 |
GET | /simulators/:udid/definition.json | SDK 引导数据:身份、屏幕矩形、边框 URL、按键 |
系统环境注入路由:姿态、铰链、位置、网络
模拟真实世界条件,全部走简单 REST:
- 🔄姿态:
POST /simulators/:udid/orientation?value=portrait|landscape-left|…;POST …/shake触发运动摇一摇; - 📐铰链(iPhone Duo):
GET/POST …/hinge,支持pose=、angle=、duration=折叠与回正; - 📍GPS:
POST/DELETE …/location设置模拟位置,删除即清除; - 📶网络限速:
GET/POST/DELETE …/network注入弱网条件; - 🚶CoreMotion:
GET/POST/DELETE …/motion注入计步、姿态等运动数据; - 🕐状态栏:
GET/POST/DELETE …/status-bar覆盖时间与电量显示; - 🎨系统界面:
GET/POST …/interface.json调外观、对比度、文字大小。
文件、摄像头与 Deep Link 路由
| 方法 | 路径 | 作用 |
|---|---|---|
POST | /simulators/:udid/files | 按扩展名上传文件到模拟器 |
POST | /simulators/:udid/apps | 安装 App 归档 |
POST | /simulators/:udid/media | 照片导入 Photos 图库 |
POST | /simulators/:udid/camera-source?name= | 为摄像头准备一张图 / 一段视频 |
POST | /simulators/:udid/openurl?url= | 打开 Deep Link |
GET | /simulators/:udid/schemes.json?q= | 查询设备已注册的 URL Scheme |
插件与 Bakery 路由:把控制能力装进服务器
| 方法 | 路径 | 作用 |
|---|---|---|
GET | /plugins.json | 已安装插件的 manifest 清单 |
POST | /plugins/:id/commands/:cmd?udid= | 执行一条插件贡献的命令 |
GET | /bakeries.json | 受信任的 bakery(插件仓库)与固定 commit |
POST | /bakeries/preview、/bakeries/install | 读取菜单 / 从受信来源安装 |
插件每次调用都会拿到一个一次性能力凭据(grant),凭据只带 manifest 声明的能力,命令结束即失效——这是它敢对网络暴露的原因。
物理设备孪生与伴生屏幕(预览)
GET /devices.json、WS /devices/:udid/…:物理设备 twin(video / motion 摄入、镜像流);GET …/companion-screens.json:CarPlay 屏 + 配对手表;POST …/carplay-display:挂载 CarPlay 平面(流式通道加display=carplay即可投到 CarPlay)。
安全须知:只信任回环 Origin
⚠️ 服务器只信任回环的Host/Origin,经反向代理的请求会得到403 forbidden origin。放行代理域名(子域可用通配):
baguette serve --allowed-hosts sim.example.com --allowed-hosts '*.example.com'其他跨站 Origin 一律拒绝;插件则走各自的 grant 凭据,不受此限制。
完整路由速查表
| 类别 | 路由 | 文档 |
|---|---|---|
| 设备 | GET /simulators、/simulators.json、POST …/boot、…/shutdown | boot |
| 输入 | POST …/input | wire.md |
| 画面 | GET …/screenshot.{jpg,png}、…/stream(WS)、…/stream.3d.*(WS) | screenshot、3d-rendering |
| 环境 | POST …/orientation、…/shake、…/location、…/motion、…/network、GET/POST …/hinge、…/status-bar | 各 feature README |
| 内容 | POST …/files、…/apps、…/media、…/camera-source、…/openurl | file-upload |
| 扩展 | /plugins.json、/plugins/:id/commands/:cmd、/bakeries.json | plugins |
| 静态页 | /farm(设备农场页)、/(302 →/simulators)、Resources/Web/静态资源 | device-farm |
一行一格的原始表格见官方文档 docs/serve.md。
延伸阅读与源码索引
- 路由权威清单:docs/serve.md
- 手势 JSON 信封与坐标约定:docs/wire.md
- 服务器参数:docs/commands.md
- 服务器为什么是"薄处理器"设计:docs/ARCHITECTURE.md
- 路由实现入口:Server.swift、ServeCommand.swift
小结:baguette serve把整个 iOS 模拟器变成了一组可预测的 HTTP/WS 资源——UDID 定设备、扩展名定格式、JSON 信封定手势。掌握上面这份清单,你就能在脚本、CI 或自定义面板里,像调用普通 API 一样驱动模拟器、录 60 fps 画面并注入真实的环境条件。
【免费下载链接】baguetteHeadless control for Apple's Simulators — 3D models, taps, swipes, multi-finger gestures, 60 fps streaming, and a multi-device farm项目地址: https://gitcode.com/gh_mirrors/baguette/baguette
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考