关于 ios-device-automation
供 AI Agent 通过截图和自然语言命令自动操作 iOS 设备的 Midscene 技能,使用 iOS 命令行依次执行界面操作并验证结果。
主要功能
- 01自然语言执行界面操作
- 02截取并分析屏幕
- 03断言屏幕状态
- 04录制短暂界面状态
- 05WebDriverAgent 请求与报告
适用场景
- 01完成 iOS 应用中的多步任务
- 02在 QA 中检查可见界面状态
- 03捕获临时通知或过渡画面
- 04通过 WebDriverAgent 检查设备
MCP 相关
iOS 命令行中的每条命令都对应 MCP 工具,AI Agent 根据截图调用这些工具控制设备。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ web-infra-dev/ midscene-skills --skill ios-device-automation安装后在 Claude Code 中输入/ios-device-automation确认已加载。
详细介绍
iOS 设备自动化
关键规则——违反规则会导致工作流失败:
- 绝不要在后台运行 midscene 命令。 每条命令都必须同步运行,以便你在决定下一步操作之前读取其输出(尤其是屏幕截图)。在后台运行会中断“截图—分析—操作”循环。
- 一次只运行一条 midscene 命令。 等待上一条命令完成,读取屏幕截图,然后再决定下一步操作。绝不要将多条命令串联执行。
- 为每条命令留出足够的执行时间。 Midscene 命令涉及 AI 推理和屏幕交互,可能比一般的 shell 命令耗时更久。一般命令需要约 1 分钟;复杂的
act命令可能需要更长时间。- 结束前务必报告任务结果。 自动化任务完成后,你必须主动向用户总结结果,包括发现的关键信息、已完成的操作、拍摄的屏幕截图以及任何相关发现。绝不要在最后一步自动化操作完成后就不作回应;用户希望在一次交互中获得完整答复。
使用 npx -y @midscene/ios@1 自动化 iOS 设备。每条 CLI 命令都直接对应一个 MCP 工具——你(AI Agent)负责根据屏幕截图决定要执行哪些操作。
act 可以执行的操作
在 iOS 上的一次 act 调用中,Midscene 可以轻点、连点两次、长按、输入、清除文本、滚动、拖动项目、用两根手指缩放、按下按键,以及使用主屏幕或应用切换器等系统导航功能;所有操作都基于当前可见屏幕进行。
前置条件
Midscene 需要具备强大视觉定位能力的模型。必须配置以下环境变量——可以设置为系统环境变量,也可以写入当前工作目录下的 .env 文件(Midscene 会自动加载 .env):
MIDSCENE_MODEL_API_KEY="your-api-key"
MIDSCENE_MODEL_NAME="model-name"
MIDSCENE_MODEL_BASE_URL="https://..."
MIDSCENE_MODEL_FAMILY="family-identifier"
示例:Gemini(Gemini-3-Flash)
MIDSCENE_MODEL_API_KEY="your-google-api-key"
MIDSCENE_MODEL_NAME="gemini-3-flash"
MIDSCENE_MODEL_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai/"
MIDSCENE_MODEL_FAMILY="gemini"
示例:Qwen 3.5
MIDSCENE_MODEL_API_KEY="your-aliyun-api-key"
MIDSCENE_MODEL_NAME="qwen3.5-plus"
MIDSCENE_MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MIDSCENE_MODEL_FAMILY="qwen3.5"
MIDSCENE_MODEL_REASONING_ENABLED="false"
# If using OpenRouter, set:
# MIDSCENE_MODEL_API_KEY="your-openrouter-api-key"
# MIDSCENE_MODEL_NAME="qwen/qwen3.5-plus"
# MIDSCENE_MODEL_BASE_URL="https://openrouter.ai/api/v1"
示例:Doubao Seed 2.0 Lite
MIDSCENE_MODEL_API_KEY="your-doubao-api-key"
MIDSCENE_MODEL_NAME="doubao-seed-2-0-lite"
MIDSCENE_MODEL_BASE_URL="https://ark.cn-beijing.volces.com/api/v3"
MIDSCENE_MODEL_FAMILY="doubao-seed"
常用模型:Doubao Seed 2.0 Lite、Qwen 3.5、Zhipu GLM-4.6V、Gemini-3-Pro、Gemini-3-Flash。
如果尚未配置模型,请让用户进行设置。支持的提供商请参阅模型配置。
命令
连接设备
npx -y @midscene/ios@1 connect
如果 WebDriverAgent 已在运行,且会话是在 Midscene 之外创建的,请同时传入 WDA 端点和外部会话 ID:
npx -y @midscene/ios@1 connect --wda-host 127.0.0.1 --wda-port 8100 --session-id <sessionId>
之后的命令如需通过现有 WDA 会话执行,请使用相同的 --wda-host、--wda-port 和 --session-id 选项。
启动应用、URL 或深层链接
如果你希望从已知应用或路由开始执行后续任务,请使用内置启动功能。请提供尽可能具体的目标,例如捆绑 ID、网页 URL、深层链接或电话/邮件链接。常见目标包括 com.apple.Preferences、https://www.apple.com、myapp://profile/user/123 和 tel:+1234567890。
发送直接设备请求
当任务需要较低层级的设备控制,而非普通的可见 UI 交互时,请使用此功能:
npx -y @midscene/ios@1 runwdarequest --method GET --endpoint /wda/screen
这不会运行 ADB 命令。在 iOS 上,底层操作是向 WebDriverAgent 发送 HTTP 请求,通常为 GET http://<wdaHost>:<wdaPort>/session/<sessionId>/wda/screen。
拍摄屏幕截图
npx -y @midscene/ios@1 take_screenshot
拍摄屏幕截图后,请读取保存的图像文件,了解当前屏幕状态,再决定下一步操作。
执行操作
使用 act 与设备交互并获取结果。它会在内部自主处理所有 UI 交互——轻点、输入、滚动、滑动、等待和导航——因此应将复杂的高层任务作为一个整体交给它,而不是拆分成多个小步骤。请用自然语言描述你要做的事以及期望的效果:
# specific instructions
npx -y @midscene/ios@1 act --prompt "type hello world in the search field and press Enter"
npx -y @midscene/ios@1 act --prompt "tap Delete, then confirm in the alert dialog"
# or target-driven instructions
npx -y @midscene/ios@1 act --prompt "open Settings and navigate to Wi-Fi, tell me the connected network name"
断言当前屏幕状态
使用 assert 验证当前屏幕是否满足自然语言描述的条件。它不会执行 UI 操作,只检查可见的屏幕状态,并且仅当断言为真时才会通过。可用于验证、QA 检查,以及在 act 后验证最终状态。
npx -y @midscene/ios@1 assert --prompt "there is a login button visible"
npx -y @midscene/ios@1 assert --prompt "the settings screen shows Wi-Fi and Bluetooth options"
默认情况下,断言失败时会抛出 AI 生成的原因。传入 --message 可改为抛出自定义错误消息,这有助于在 QA 和 CI 日志中显示预期结果。
npx -y @midscene/ios@1 assert \
--prompt "the order confirmation screen is visible" \
--message "the order should be confirmed after tapping Pay"
当断言需要与参考图像(图标、徽标、截图)进行比较时,传入 --image 指定 URL/路径,并通过 --image-name 指定显示名称。每个 --image 的值可以是 http(s) 链接、data: URI 或本地文件路径。需要附加多张图像时,按相同顺序重复这两个标志。如果模型无法直接访问 URL,请添加 --convertHttpImage2Base64 true。需要 @midscene/[email protected]+。
npx -y @midscene/ios@1 assert \
--prompt "the visible app icon matches the supplied reference image" \
--image "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png" \
--image-name "icon" \
--convertHttpImage2Base64 true
# or with a local file
npx -y @midscene/ios@1 assert \
--prompt "the header on screen matches the local screenshot" \
--image "./fixtures/header.png" \
--image-name "header"
# multiple reference images — pair --image and --image-name by order
npx -y @midscene/ios@1 assert \
--prompt "the screen shows both the app icon and the header" \
--image "./fixtures/icon.png" --image-name "icon" \
--image "./fixtures/header.png" --image-name "header"
录制并断言瞬时 UI
如果待验证的状态可能在当前屏幕断言运行前消失(例如 Toast、加载横幅、动画或过渡效果),请使用录制:
# Terminal 1: keep this foreground command running
npx -y @midscene/ios@1 record start --device-id <udid> \
--output ./submission-observation.json
# Terminal 2, while Terminal 1 records
npx -y @midscene/ios@1 act --device-id <udid> \
--prompt "tap the Submit button"
# Send Ctrl+C to Terminal 1 and wait for the saved-path message, then assert
npx -y @midscene/ios@1 assert --device-id <udid> \
--record ./submission-observation.json \
--prompt "a success toast appeared during submission"
对 record start 传入目标标志、采集标志和 --output,然后等待 Recording. Press Ctrl+C to stop and save.。让录制器在专用终端中以前台进程运行;不要添加 shell &。手动操作,或从第二个终端执行操作,然后向录制器发送 Ctrl+C,并等待它打印出已保存路径后再进行断言。启用 WDA MJPEG 帧源时,录制会使用该帧源,否则会回退到定时截取屏幕截图。可选的采集标志包括 --interval-ms、--max-frames 和 --watchdog-ms;--max-frames 会限制采样帧数,清单中可能会额外包含一帧最终代表性帧。默认看门狗会在五分钟后完成并保存录制;--watchdog-ms 0 则会禁用此安全限制。输出是一份 JSON 清单和一个相邻的 <name>.frames 图像目录,而不是编码后的视频或归档文件。清单包含相对 JPEG/PNG 路径,不包含 base64 图像数据。请将 JSON 文件和图像目录放在一起保存或移动,并将 JSON 路径传给 assert --record。如果只关心当前屏幕,请使用不带 --record 的普通 assert。
使用参考图像进行精确定位
当用户提供截图、图标、徽标或参考图像并要求精确匹配时,优先使用 tap --locate,而不是通用的 act --prompt。将 --locate 作为 JSON 传入。prompt 描述目标,images 提供带名称的参考图像;如果模型可能无法直接访问图像 URL,convertHttpImage2Base64: true 会很有用。
npx -y @midscene/ios@1 tap --locate '{
"prompt": "tap the area contains the image",
"images": [
{
"name": "target image",
"url": "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
}
],
"convertHttpImage2Base64": true
}'
其他接受 locate 参数的命令也支持相同格式的 locate JSON。
断开连接
npx -y @midscene/ios@1 disconnect
使用报告文件
建议先使用生成的 HTML 报告供人工阅读。报告包含逐步执行详情,以及每项操作的回放视频,因此更容易了解发生了什么并排查问题。
如果其他技能或工具需要使用该报告,请先通过同一平台 CLI 包中的 report-tool 转换报告。对于基于大模型的工作流,优先使用 Markdown;如果需要以编程方式处理报告,则使用 JSON。
npx -y @midscene/ios@1 report-tool --action to-markdown --htmlPath ./midscene_run/report/.../index.html --outputDir ./output-markdown
npx -y @midscene/ios@1 report-tool --action split --htmlPath ./midscene_run/report/.../index.html --outputDir ./output-data
工作流模式
由于 CLI 命令在多次调用之间无状态,请遵循以下模式:
- 连接以建立会话
- 启动目标应用并截取屏幕截图以查看当前状态,确保应用已启动并在屏幕上可见。
- 执行操作:使用
act执行所需操作或基于目标的指令。使用assert验证操作后的屏幕状态;对于瞬时状态工作流,也可以在专用终端中持续运行record start --output ...,使用 Ctrl+C 停止录制,然后使用assert --record。 - 断开连接
- 报告结果——总结完成的工作,展示任务中提取的关键发现和数据,并列出生成的文件(屏幕截图、日志等)及其路径
最佳实践
- 具体描述 UI 元素:不要使用模糊描述,而要提供清晰、具体的细节。例如,说
"右上角的 Settings 图标",而不是"图标"。 - 尽可能描述位置:通过描述元素的位置帮助定位(例如,
"右上方的搜索图标"、"列表中的第三项")。 - 绝不要在后台运行:每条 midscene 命令都必须同步运行——后台执行会破坏截图-分析-操作循环。
- 将相关操作合并到一个
act命令中:在同一个应用中连续执行多个操作时,将它们合并到一个act提示词中,而不是拆分成多个命令。例如,“打开 Settings,点击 Wi-Fi,并检查已连接的网络”应作为一次act调用,而不是三次。这样可以减少往返次数,避免不必要的截图-分析循环,速度也会快很多。 - 选择合适的验证窗口:对于当前屏幕,使用
assert --prompt "..."。对于 Toast、横幅、动画或过渡效果,在专用终端中运行record start --output ...,执行交互,使用 Ctrl+C 停止录制,等待保存路径消息,然后将生成文件传给assert --record。 - 完成后务必报告结果:自动化任务完成后,你必须主动向用户展示结果,无需等待用户询问。内容包括:(1) 对用户原始问题的回答或所请求任务的结果,(2) 执行期间提取或观察到的关键数据,(3) 屏幕截图和其他生成文件及其路径,(4) 所采取步骤的简要总结。最后一条自动化命令执行后,切勿默默结束——用户期望在一次交互中获得完整结果。
- 提供参考图像时优先使用
tap --locate:如果用户分享了屏幕截图、图标或徽标,并希望定位完全一致的视觉目标,请使用包含多模态locateJSON 对象(例如{ "prompt": "...", "images": [...] })的tap --locate,而不要只依赖act --prompt。
示例——警告对话框交互:
npx -y @midscene/ios@1 act --prompt "tap the Delete button and confirm in the alert dialog"
npx -y @midscene/ios@1 take_screenshot
示例——表单交互:
npx -y @midscene/ios@1 act --prompt "fill in the username field with 'testuser' and the password field with 'pass123', then tap the Login button"
npx -y @midscene/ios@1 take_screenshot
提高精度(Deep Locate / Deep Think)
Midscene 难以完成任务时,可使用两个可选的全局标志。可将它们放在命令中的任意位置(子命令前后均可);设置后,相关操作会默认使用它们,因此无需传递单次调用参数。
--deep-locate— 额外进行一轮视觉推理,以精确定位目标元素。当操作点击到错误位置(位置漂移/偏移)时使用。它适用于所有需要定位元素的操作,包括tap --locate以及act内部执行的定位。--deep-think— 使用更深入的推理来规划act(提供更丰富的上下文并拆解子目标)。复杂的多步骤act指令可使用此标志;它只影响规划。
这两个标志会略微降低速度,以换取更好的结果,也可以同时使用。
# more accurate element location (helps act's internal locating too)
npx -y @midscene/ios@1 act --deep-locate --prompt "tap the small back chevron in the top-left corner"
# deeper planning for a complex, multi-step act
npx -y @midscene/ios@1 act --deep-think --prompt "complete the multi-step signup form and submit"
# combine both
npx -y @midscene/ios@1 act --deep-locate --deep-think --prompt "open Settings, go to Display & Brightness, and turn on Dark Mode"
故障排除
WebDriverAgent 未运行
**症状:**连接被拒绝或请求超时。 解决方案:
- 确保 WebDriverAgent 已安装并正在设备上运行。
- 如果另一个工具创建了 WDA 会话,请使用
--session-id,以及相匹配的--wda-host和--wda-port显式传入该会话。 - 请参阅 https://midscenejs.com/usage-ios.html 了解设置说明。
未找到设备
**症状:**未检测到设备或出现连接错误。 解决方案:
- 确保设备已通过 USB 连接并设为信任。
API 密钥问题
**症状:**出现身份验证或模型错误。 解决方案:
- 检查
.env文件是否包含MIDSCENE_MODEL_API_KEY=<your-key>。 - 请参阅 https://midscenejs.com/zh/model-common-config.html 了解详情。
@midscene/* 依赖版本过旧
**症状:**行为异常、缺少功能或出现版本不匹配错误。 解决方案:
- 检查本地版本:
npm ls @midscene/ios @midscene/core @midscene/shared(或pnpm why @midscene/ios)。 - 检查最新版本:
npm view @midscene/ios version、npm view @midscene/core version、npm view @midscene/shared version。 - 升级依赖:
npm i @midscene/ios@latest @midscene/core@latest @midscene/shared@latest。