基于 Python+Flask+Vue3完成 iOS Web 端投屏互动控制平台

发布时间:2026/6/10 7:30:33

基于 Python+Flask+Vue3完成 iOS Web 端投屏互动控制平台 一个纯浏览器的 iOS 真机远程镜像 / 控制 / 运维平台。无需安装任何客户端即可在 Windows / macOS / Linux 上运行。已适配iOS 26。文章目录一、项目概述二、使用指南1、环境准备2、安装启动3、连接 iPhone 并开始操作三、功能特性1、远程镜像与控制2、单设备视图 / 多设备网格双模式3、设备占用预约机制4、UI 自动化定位5、文件浏览器6、应用管理7、账号体系与权限8、实时系统日志9、国际化与多主题10、环境需求与常见问题四、项目框架代码1、项目框架2、核心代码片段1跨平台一键启动器2IOSAdapter连接 / 断开核心流程3ProductType 友好名映射节选4项目架构时序图五、结语一、项目概述WebAppFlaskauto-iOS是一款基于Python Flask Flask-SocketIO后端、Vue 3 Vite前端的 Web 端 iOS 投屏互动控制平台。启动浏览器即可使用发现已连接到本机的 iPhone 真机实时镜像设备屏幕MJPEG 主路 可选 WebRTC 低延迟远程触控 / 滑动 / 文本输入 / 截图浏览设备文件、安装卸载应用、运行 UI 自动化定位查看实时系统日志、设备硬件信息底层链路pymobiledevice3纯 Python负责设备发现、usbmux 端口转发、WDA HTTP 通信WebDriverAgent (WDA)负责实际的控制指令下发go-ios可选仅 iOS 17走用户态 RSD 隧道拉起 WDA免管理员权限✨ 重点适配iOS 17 起 RSD 隧道在 Windows 上通需常要管理员权限本项目通过内置的 go-ios 用户态隧道彻底绕开已在 iOS 26.5 真机验证可用。二、使用指南1、环境准备组件版本要求Python3.10 及以上Node.js18 及以上构建前端用iTunes / Apple Mobile Device SupportWindows 用户必装提供 usbmux 驱动浏览器Chrome / Edge / Safari 最新版iOS 设备侧iOS 17 需要在「设置 → 隐私与安全 → 开发者模式」打开开发者模式首次插线信任本机2、安装启动# 1. 克隆仓库gitclone https://github.com/zhoujun94511/WebAppFlaskauto-iOS.gitcdWebAppFlaskauto-iOS# 2. 创建 Python 虚拟环境python-mvenv .venv .venv\Scripts\activate# Windows# source .venv/bin/activate # macOS / Linux# 3. 安装依赖pipinstall-rrequirements.txt# 4. 复制环境变量模板默认值即可启动cp.env.example .env# 5. 安装并构建前端cdfrontendnpminstallnpmrun buildcd..# 6. 一键启动自动拉起后端 :5001 Vite 开发服务 :5173python start_dev.py打开浏览器访问 http://localhost:5001/ 即可。默认超级管理员账号用户名superadmin密码superadmin1233、连接 iPhone 并开始操作用数据线插上 iPhone在 iOS 端弹窗中信任本机登录后左侧导航点「设备」即可看到列表点击某台设备的「连接」按钮等待约 10-20 秒首次启动 WDA 较慢连接成功后切到「单屏」模式屏幕画面即时呈现光环代表在线 streaming鼠标点击 / 拖动 触控 / 滑动右侧面板可切换控制 / 应用 / 文件 / 日志 / 自动化三、功能特性1、远程镜像与控制MJPEG 主路 截图轮询兜底跨平台、稳定可靠可选 WebRTCaiortcH264 优先、VP8 兜底码率可调宿主侧 libx264 软编触控全覆盖tap / swipe / long-press / double-tap / 文本输入 / 截图系统按键Home / 锁屏 / 音量 ± / 方向 D-pad合成 WDA swipe无障碍快捷开关辅助触控、旁白VoiceOver、缩放经 go-ios2、单设备视图 / 多设备网格双模式单设备模式左侧设备信息卡 中央真机投屏 右侧可弹出的控制抽屉控制 / 自动化 / 应用 / 文件 / 日志多设备网格自动按可用宽度排版每台设备进网格时自动降到 70% 分辨率减负设备 streaming 中卡片自带双层蓝色光环外层卡片描边 内层屏幕区域 pulsing 双线视觉与 Android 端一致3、设备占用预约机制真机稀缺多人争抢是日常痛点。本项目内置完整的预约系统任意普通用户可对未被占用的设备发起占用自选时长默认 30 分钟占用期间仅占用者可控制其它用户只读可看不可点三种释放路径统一本人取消 / 管理员强制 / 到期清扫线程自动回收数据库device_id主键 UNIQUE 约束解决并发抢占败者得 IntegrityError 而非半成功4、UI 自动化定位支持四种定位方式accessibility id / predicate / xpath / class / name内置 find / tap / type 三类动作当前前台应用实时显示bundleId 进程名页面源码XML格式化展示— 一键拉取整页 XML自动缩进、可折叠5、文件浏览器可展开 / 收起的目录树点击文件直接下载到本机图片 / 音视频 / PDF / 文本类支持应用内预览弹层拖拽或选取文件即可上传到设备目录目标目录与当前展开节点联动6、应用管理列举已安装应用含 BundleId、版本、显示名启动 / 结束应用安装.ipa包拖拽到面板或文件选择卸载应用带二次确认7、账号体系与权限三级角色角色权限超级管理员super_admin全权限管理所有用户的角色、邮箱、密码、启停状态管理员admin管理普通用户、强制释放设备占用普通用户user自助注册、自助占用 / 释放设备、控制已占用的设备服务端会话cookie 内存 登录闸门未登录访问任何/api/*都返回 401登录失败限流连续失败 5 次 60 秒锁定管理面板仅管理员可见建号 / 改邮箱 / 重置密码 / 改角色 / 启停 / 删除8、实时系统日志后端用 go-ios syslog 拉设备实时日志通过SSE推到前端客户端支持正则 / 进程 / 级别三重过滤手动启停按钮 —— 不看就停避免空闲时长连接占用资源9、国际化与多主题三语zh-CN简体中文 /zh-TW繁體中文 /enEnglish切换语言时自动同步html langdocument.title浏览器标签页 所有界面文案浅 / 深双主题 自动跟随系统10、环境需求与常见问题问题排查方向设备列表为空检查 iTunes 是否装、数据线是否原装、设备是否信任本机连接超时 / WDA 起不来开发者模式有没开首次启动 WDA 耗时较长10-20 秒Windows 报wintun.dll缺失本仓库resources/wintun/arch/已内置go-ios 会自动加载WebRTC 看不到画面检查.env里IOS_ENABLE_WEBRTC1浏览器需要支持 H264多人同时连接断流看是否两个用户都拿了占用 — 设备占用机制限定同时仅一人可控四、项目框架代码1、项目框架WebAppFlaskauto-iOS/ ├── app.py # Flask Socket.IO 入口蓝图注册、登录闸门、SPA 托管 ├── start_dev.py # 跨平台一键启动器后端 5001 Vite 5173 ├── requirements.txt │ ├── api/ # HTTP / Socket.IO 路由薄适配层 │ ├── auth_api.py # 登录 / 注册 / 会话 / 用户管理 │ ├── reservations_api.py # 设备占用 REST │ ├── devices_api.py # 设备列表 / 连接 / 断开 / WDA 状态 │ ├── control_api.py # tap / swipe / input / 截图 / 启动 / 弹窗 / 剪贴板 │ ├── stream_api.py # 画面流启停 / 质量 / 分辨率 │ ├── files_api.py # 文件树 / 下载 / 上传 / 内联预览 │ ├── apps_api.py # 应用列举 / 安装 / 卸载 │ └── automation_api.py # WDA 选择器 find/tap/type │ ├── services/ # 业务逻辑层 │ ├── app_db.py # SQLite 连接、建表、预置账号 │ ├── auth_service.py # 口令哈希、会话令牌、角色 │ ├── reservation_service.py # 设备占用claim / release / sweep │ ├── device_info.py # lockdown 信息聚合 │ ├── stream_bridge.py # 画面帧 → Socket.IO │ └── webrtc_bridge.py # aiortc 管线JpegVideoTrack 码率调优 │ ├── ios/ # iOS 平台适配 │ ├── ios_adapter.py # 统一门面发现 / 连接 / 控制 / 流 │ ├── go_ios.py # go-ios 封装隧道 / runwda / fsync / apps │ ├── tunnel_manager.py # 用户态 RSD 隧道生命周期 │ ├── port_forward.py # usbmux 端口转发 │ ├── device_marketing.py # ProductType → 营销名映射iPhone 15 Pro Max 等 │ └── screen_provider/ # wda_mjpeg / wda_screenshot 插件 │ ├── frontend/ # Vue 3 Vite 前端 │ └── src/ │ ├── components/ # LoginView / DeviceStage / DeviceMatrix / ... │ ├── composables/ # useAuth / useDevices / useWebRTC / useUiI18n ... │ └── locales/ # zh-CN / zh-TW / en 三语 JSON │ ├── resources/ │ ├── executable/os/ # 内置 go-ios 二进制 │ └── wintun/arch/ # Windows 隧道所需 wintun.dll │ └── tests/ # pytest 白盒测试2、核心代码片段1跨平台一键启动器# start_dev.py简化版importos,sys,signal,subprocessdefstart_backend():returnsubprocess.Popen([sys.executable,app.py],env{**os.environ,PORT:5001},)defstart_frontend():returnsubprocess.Popen([npm,run,dev],cwdfrontend,shell(os.nament),)if__name____main__:backendstart_backend()frontendstart_frontend()print([start_dev] CtrlC to stop both.)try:backend.wait()finally:frontend.terminate()2IOSAdapter连接 / 断开核心流程# ios/ios_adapter.py节选classIOSAdapter:defconnect(self,udid:str)-None:# 1) 起用户态隧道iOS 17 才需要免管理员self.tunnel_manager.ensure(udid)# 2) 通过 go-ios runwda 拉起 WebDriverAgentself.wda_launcher.start(udid)# 3) usbmux 端口转发到 WDA HTTP8100和 MJPEG9100self.port_forward.start(udid,18100,8100)self.port_forward.start(f{udid}#mjpeg,19100,9100)# 4) HTTP probe确认 WDA 起来了self.wda_controller.wait_ready(udid)defdisconnect(self,udid:str)-None:# 关 WebRTC peer 在前撕端口转发在后 —— 避免读线程拿到 ECONNRESETwithsuppress(Exception):self.webrtc.stop_device(udid)self.stop_stream(udid)# 关 WDA 进程 控制器self.wda_launcher.stop(udid)# 最后撕端口转发self.port_forward.stop_forward(udid)self.port_forward.stop_forward(f{udid}#mjpeg)3ProductType 友好名映射节选# ios/device_marketing.py节选MARKETING_NAMES:dict[str,str]{# iPhone 17 series (2025)iPhone18,1:iPhone 17 Pro,iPhone18,2:iPhone 17 Pro Max,iPhone18,3:iPhone 17,iPhone18,4:iPhone Air,iPhone18,5:iPhone 17e,# iPhone 16 series (2024)iPhone17,1:iPhone 16 Pro,iPhone17,2:iPhone 16 Pro Max,# ... 一直覆盖到 2007 年原代 iPhone63 条iPhone1,1:iPhone,}defmarketing_name(product_type:str)-str:ProductType → 营销名未知则原样返回 identifier。returnMARKETING_NAMES.get(product_type,product_type)4项目架构时序图浏览器 (Vue3 SPA) │ HTTP /api/* Socket.IO(设备/画面/控制/日志) WebRTC(可选, 视频控制 DataChannel) ▼ ▼ ▼ Flask Flask-SocketIO (async_modethreading) │ api/ → services/ → ios/ios_adapter.py ▼ IOSAdapter ├─ DeviceManager pymobiledevice3:设备发现 / lockdown 信息 ┐ Flask 原生主路径 ├─ PortForward pymobiledevice3 usbmux:本地端口 → WDA 8100/9100 │ (无需隧道) ├─ WDAController WebDriverAgent HTTP:tap/swipe/text/截图/应用/弹窗 ┘ ├─ GoIOS Tunnel go-ios:用户态 RSD 隧道(免管理员) runwda ← iOS 17 拉起 ├─ ScreenProvider wda_mjpeg(主) / wda_screenshot(兜底) └─ StreamBridge 画面帧 → Socket.IO roomudid WebRTCBridge → aiortc(JpegVideoTrack, 宿主侧 libx264) ▼ SQLite (账号 / 会话 / 设备占用)五、结语本项目的初衷是把 iOS 真机变成可调度、可审计、零客户端的共享资源。和市面常见的 Appium / tidevice 方案相比主要区别在直接用 HTTP 与 WDA 通信—— 不装 Appium Server启动链路短pymobiledevice3 go-ios 双引擎互补—— iOS 17 免管理员模式可真实运行业务层完备—— 账号、占用、审计、面板一体开箱即用后续规划流媒体输出适配与 Android 姊妹项目 WebAppFlaskscrcpy 合并为统一跨平台运维台如果觉得有用欢迎 Star ⭐https://github.com/zhoujun94511/WebAppFlaskauto-iOS有问题、想法或合作意向欢迎 Issue 或评论区交流。

相关新闻