mcpField
I
ios-device-automation

ios-device-automation

github.com/web-infra-devAgent 工作流3183.3k 次安装11 周前更新
代码仓库

关于 ios-device-automation

供 AI Agent 通过截图和自然语言命令自动操作 iOS 设备的 Midscene 技能,使用 iOS 命令行依次执行界面操作并验证结果。

主要功能

  1. 01自然语言执行界面操作
  2. 02截取并分析屏幕
  3. 03断言屏幕状态
  4. 04录制短暂界面状态
  5. 05WebDriverAgent 请求与报告

适用场景

  1. 01完成 iOS 应用中的多步任务
  2. 02在 QA 中检查可见界面状态
  3. 03捕获临时通知或过渡画面
  4. 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 设备自动化

关键规则——违反规则会导致工作流失败:

  1. 绝不要在后台运行 midscene 命令。 每条命令都必须同步运行,以便你在决定下一步操作之前读取其输出(尤其是屏幕截图)。在后台运行会中断“截图—分析—操作”循环。
  2. 一次只运行一条 midscene 命令。 等待上一条命令完成,读取屏幕截图,然后再决定下一步操作。绝不要将多条命令串联执行。
  3. 为每条命令留出足够的执行时间。 Midscene 命令涉及 AI 推理和屏幕交互,可能比一般的 shell 命令耗时更久。一般命令需要约 1 分钟;复杂的 act 命令可能需要更长时间。
  4. 结束前务必报告任务结果。 自动化任务完成后,你必须主动向用户总结结果,包括发现的关键信息、已完成的操作、拍摄的屏幕截图以及任何相关发现。绝不要在最后一步自动化操作完成后就不作回应;用户希望在一次交互中获得完整答复。

使用 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 命令在多次调用之间无状态,请遵循以下模式:

  1. 连接以建立会话
  2. 启动目标应用并截取屏幕截图以查看当前状态,确保应用已启动并在屏幕上可见。
  3. 执行操作:使用 act 执行所需操作或基于目标的指令。使用 assert 验证操作后的屏幕状态;对于瞬时状态工作流,也可以在专用终端中持续运行 record start --output ...,使用 Ctrl+C 停止录制,然后使用 assert --record。
  4. 断开连接
  5. 报告结果——总结完成的工作,展示任务中提取的关键发现和数据,并列出生成的文件(屏幕截图、日志等)及其路径

最佳实践

  1. 具体描述 UI 元素:不要使用模糊描述,而要提供清晰、具体的细节。例如,说 "右上角的 Settings 图标",而不是 "图标"。
  2. 尽可能描述位置:通过描述元素的位置帮助定位(例如,"右上方的搜索图标"、"列表中的第三项")。
  3. 绝不要在后台运行:每条 midscene 命令都必须同步运行——后台执行会破坏截图-分析-操作循环。
  4. 将相关操作合并到一个 act 命令中:在同一个应用中连续执行多个操作时,将它们合并到一个 act 提示词中,而不是拆分成多个命令。例如,“打开 Settings,点击 Wi-Fi,并检查已连接的网络”应作为一次 act 调用,而不是三次。这样可以减少往返次数,避免不必要的截图-分析循环,速度也会快很多。
  5. 选择合适的验证窗口:对于当前屏幕,使用 assert --prompt "..."。对于 Toast、横幅、动画或过渡效果,在专用终端中运行 record start --output ...,执行交互,使用 Ctrl+C 停止录制,等待保存路径消息,然后将生成文件传给 assert --record。
  6. 完成后务必报告结果:自动化任务完成后,你必须主动向用户展示结果,无需等待用户询问。内容包括:(1) 对用户原始问题的回答或所请求任务的结果,(2) 执行期间提取或观察到的关键数据,(3) 屏幕截图和其他生成文件及其路径,(4) 所采取步骤的简要总结。最后一条自动化命令执行后,切勿默默结束——用户期望在一次交互中获得完整结果。
  7. 提供参考图像时优先使用 tap --locate:如果用户分享了屏幕截图、图标或徽标,并希望定位完全一致的视觉目标,请使用包含多模态 locate JSON 对象(例如 { "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 密钥问题

**症状:**出现身份验证或模型错误。 解决方案:

@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。

评论

支持 Markdown