与 iOS(WebDriverAgent) 集成
在使用 WebDriverAgent 连接 iOS 设备后,你可以使用 Midscene JavaScript SDK 来控制 iOS 设备。
关于 WebDriver 和 Midscene 的关系
WebDriver 是一套由 W3C 制定的用于浏览器自动化的标准协议,它提供了一个统一的 API 来控制不同的浏览器和应用程序。WebDriver 协议定义了客户端和服务器之间的通信方式,使得自动化工具能够跨平台地控制各种用户界面。
在 Appium 团队及其他开源社区的努力下,业界已经有了许多优秀的库将桌面、移动端等设备的自动化操作转化为 WebDriver 协议。这些工具包括:
- Appium - 跨平台移动自动化框架
- WebDriverAgent - 专门用于 iOS 设备自动化的服务
- Selenium - Web 浏览器自动化工具
- WinAppDriver - Windows 应用程序自动化工具
Midscene 适配了 WebDriver 协议,这意味着开发者可以使用 AI 模型对支持 WebDriver 的任何设备进行智能化的自动化操作。通过这种设计,Midscene 不仅能够控制传统的点击、输入等基础操作,还能够:
- 理解界面内容和上下文
- 执行复杂的多步骤操作
- 进行智能断言和验证
- 提取和分析界面数据
在 iOS 平台上,Midscene 通过 WebDriverAgent 连接 iOS 设备,让你能够使用自然语言描述的方式来控制 iOS 应用和系统。
准备 WebDriver 服务
在开始之前,你需要先设置 iOS 开发环境:
- macOS(iOS 开发必需)
- Xcode 和 Xcode 命令行工具
- iOS 模拟器或真机设备
配置 环境
在使用 Midscene iOS 之前,需要先准备 WebDriverAgent 服务。请参考官方文档进行设置:
验证环境配置
配置完成后,可以通过访问 WebDriverAgent 的状态接口来验证 服务是否启动:
访问地址:http://localhost:8100/status
正确响应示例:
{
"value": {
"build": {
"version": "10.1.1",
"time": "Sep 24 2025 18:56:41",
"productBundleIdentifier": "com.facebook.WebDriverAgentRunner"
},
"os": {
"testmanagerdVersion": 65535,
"name": "iOS",
"sdkVersion": "26.0",
"version": "26.0"
},
"device": "iphone",
"ios": {
"ip": "10.91.115.63"
},
"message": "WebDriverAgent is ready to accept commands",
"state": "success",
"ready": true
},
"sessionId": "BCAD9603-F714-447C-A9E6-07D58267966B"
}
如果能够正常访问该端点并返回类似上述的 JSON 响应,说明 WebDriverAgent 已经正确配置并运行。
配置 AI 模型服务
将你的模型配置写入环境变量,可参考 模型策略 了解更多细节。
export MIDSCENE_MODEL_BASE_URL="https://替换为你的模型服务地址/v1"
export MIDSCENE_MODEL_API_KEY="替换为你的 API Key"
export MIDSCENE_MODEL_NAME="替换为你的模型名称"
export MIDSCENE_MODEL_FAMILY="替换为你的模型系列"
更多配置信息请参考 模型策略 和 模型配置。
集成 Midscene
第一步:安装依赖
npm install @midscene/ios --save-dev
yarn add @midscene/ios --save-dev
pnpm add @midscene/ios --save-dev
bun add @midscene/ios --save-dev
deno add npm:@midscene/ios --save-dev
第二步:编写脚本
这里以使用 iOS Safari 浏览器搜索耳机为例。
编写下方代码,保存为 ./demo.ts
./demo.ts
import {
IOSAgent,
IOSDevice,
agentFromWebDriverAgent,
} from '@midscene/ios';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
Promise.resolve(
(async () => {
// 方法一:直接创建设备和 Agent
const page = new IOSDevice({
wdaPort: 8100,
wdaHost: 'localhost',
});
// 👀 初始化 Midscene agent
const agent = new IOSAgent(page, {
aiActionContext:
'如果出现位置、权限、用户协议等弹窗,点击同意。如果出现登录页面,关闭它。',
});
await page.connect();
// 方法二:或者使用便捷函数(推荐)
// const agent = await agentFromWebDriverAgent({
// wdaPort: 8100,
// wdaHost: 'localhost',
// aiActionContext: '如果出现位置、权限、用户协议等弹窗, 点击同意。如果出现登录页面,关闭它。',
// });
// 👀 打开 ebay.com 网页
await page.launch('https://ebay.com');
await sleep(3000);
// 👀 输入关键词,执行搜索
await agent.aiAct('在搜索框输入 "Headphones",敲回车');
// 👀 等待加载完成
await agent.aiWaitFor('页面中至少有一个耳机商品');
// 或者你也可以使用一个普通的 sleep:
// await sleep(5000);
// 👀 理解页面内容,提取数据
const items = await agent.aiQuery(
'{itemTitle: string, price: Number}[], 找到列表里的商品标题和价格',
);
console.log('耳机商品信息', items);
// 👀 用 AI 断言
await agent.aiAssert('界面中有多个耳机产品');
await page.destroy();
})(),
);
第三步:运行
使用 tsx 来运行
稍等片刻,你会看到如下输出:
[
{
itemTitle: 'AirPods Pro (2nd generation) with MagSafe Charging Case (USB-C)',
price: 249
},
{
itemTitle: 'Sony WH-1000XM4 Wireless Premium Noise Canceling Overhead Headphones',
price: 278
}
]
第四步:查看运行报告
当上面的命令执行成功后,会在控制台输出:Midscene - report file updated: /path/to/report/some_id.html,通过浏览器打开该文件即可看到报告。
构造函数与接口
IOSDevice 的构造函数
IOSDevice 的构造函数支持以下参数:
opts?: IOSDeviceOpt - 可选参数,用于初始化 IOSDevice 的配置
wdaPort?: number - 可选参数,WebDriverAgent 端口。默认值为 8100。
wdaHost?: string - 可选参数,WebDriverAgent 主机。默认值为 'localhost'。
autoDismissKeyboard?: boolean - 可选参数,是否在输入文本后自动关闭键盘。默认值为 true。
customActions?: DeviceAction<any>[] - 可选参数,自定义设备动作列表。
iOS Agent 上的更多接口
除了 API 参考 中的通用 Agent 接口,IOSAgent 还提供了一些其他接口:
agent.launch()
启动一个网页或原生 iOS 应用。
function launch(uri: string): Promise<void>;
-
参数:
uri: string - 要打开的 uri,可以是网页 url、原生 app 的 bundle identifier 或自定义 URL scheme
-
返回值:
-
示例:
import { IOSAgent, IOSDevice, agentFromWebDriverAgent } from '@midscene/ios';
// 方法一:手动创建设备和 Agent
const page = new IOSDevice();
const agent = new IOSAgent(page);
await page.connect();
// 方法二:使用便捷函数(推荐)
const agent = await agentFromWebDriverAgent();
await agent.launch('https://www.apple.com'); // 打开网页
await agent.launch('com.apple.mobilesafari'); // 启动 Safari
await agent.launch('com.apple.Preferences'); // 启动设置应用
await agent.launch('myapp://profile/user/123'); // 打开应用深度链接
await agent.launch('tel:+1234567890'); // 拨打电话
await agent.launch('mailto:[email protected]'); // 发送邮件
agent.runWdaRequest()
直接调用 WebDriverAgent 的 API 接口。
注意:该方法允许你直接调用 WebDriverAgent 提供的底层 API,适用于需要执行特定 WDA 操作的场景。
function runWdaRequest(
method: string,
endpoint: string,
data?: Record<string, any>,
): Promise<any>;
-
参数:
method: string - HTTP 请求方法(GET, POST, DELETE 等)
endpoint: string - WebDriver API 端点路径
data?: Record<string, any> - 可选的请求体数据(JSON 对象)
-
返回值:
Promise<any> - 返回 API 响应结果
-
示例:
import { IOSAgent, IOSDevice, agentFromWebDriverAgent } from '@midscene/ios';
const agent = await agentFromWebDriverAgent();
// 获取屏幕信息
const screenInfo = await agent.runWdaRequest('GET', '/wda/screen');
console.log(screenInfo); // { value: { scale: 3, ... } }
// 按下 Home 键
const result = await agent.runWdaRequest('POST', '/session/test/wda/pressButton', {
name: 'home'
});
// 获取设备信息
const deviceInfo = await agent.runWdaRequest('GET', '/wda/device/info');
在 YAML 脚本中使用
除了在 JavaScript/TypeScript 中使用这些方法,你还可以在 YAML 脚本中使用 iOS 的平台特定动作。
要了解如何在 YAML 脚本中使用 runWdaRequest 和 launch 动作,请参考 YAML 脚本中的 iOS 平台特定动作。
agent.home()
返回到 iOS 主屏幕。
function home(): Promise<void>;
-
参数:无
-
返回值:Promise<void>
-
示例:
import { IOSAgent, agentFromWebDriverAgent } from '@midscene/ios';
const agent = await agentFromWebDriverAgent();
await agent.home(); // 回到主屏幕
agent.appSwitcher()
打开 iOS 多任务切换界面。
function appSwitcher(): Promise<void>;
-
参数:无
-
返回值:Promise<void>
-
示例:
import { IOSAgent, agentFromWebDriverAgent } from '@midscene/ios';
const agent = await agentFromWebDriverAgent();
await agent.appSwitcher(); // 打开多任务切换界面
agentFromWebDriverAgent() (推荐)
通过连接 WebDriverAgent 服务创建 IOSAgent,这是最简便的方式。
function agentFromWebDriverAgent(
opts?: PageAgentOpt & IOSDeviceOpt,
): Promise<IOSAgent>;
-
参数:
opts?: PageAgentOpt & IOSDeviceOpt - 可选参数,用于初始化 IOSAgent 的配置,其中 PageAgentOpt 参考 构造器,IOSDeviceOpt 的配置值参考 IOSDevice 的构造函数
-
返回值:
Promise<IOSAgent> 返回一个 IOSAgent 实例
-
示例:
import { agentFromWebDriverAgent } from '@midscene/ios';
// 使用默认 WebDriverAgent 地址 (localhost:8100)
const agent = await agentFromWebDriverAgent();
// 使用自定义 WebDriverAgent 地址
const agent = await agentFromWebDriverAgent({
wdaHost: 'localhost',
wdaPort: 8100,
aiActionContext: '如果出现弹窗,点击同意',
});