真正要交付的是设备工作流。
需求可以归纳为:开发者在桌面工作台新增「设备」面板,就能启动一台 iPhone、安装自己的应用、看到画面,并把点击、输入、截图等能力交给自动化工具。安装环境、定位失败、维护版本,应该由工作台承担。
本方案把提供的讨论截图作为需求背景;其中关于内存、API 和 App 兼容性的判断均重新核验。公开页面采用概括描述,不附内部聊天截图、人员信息或业务安装包。
| 路线 | 适用场景 | 主要代价 | 本方案决策 |
|---|---|---|---|
| Xcode Simulator | 有源码、能产出 Simulator .app 的日常客户端开发 | Xcode 与 Runtime 体积;真机 IPA 不能直接作为模拟器构建运行 | 产品默认候选;由 simctl 管生命周期,idb/原生桥接补充交互 |
| 本地 vphone | 研究型 iOS 环境,验证受控开发 IPA 与自动化能力 | Apple Silicon、研究虚拟机授权、固件与管理员操作 | 首轮技术 PoC;在明确具备条件的机器启用 |
| 远端物理 Mac + vphone | 用户机器不能改系统设置,仍需要 vphone 能力 | 设备池、鉴权、流媒体、隔离与运营成本 | 严格零本地配置场景的候选;不是当前已交付服务 |
| 真机 / 设备云 | 硬件、签名、风控与真实环境一致性验证 | 配对、设备占用、账户与供应商集成 | 业务验收补充,不将虚拟机结论直接外推真机 |
Simulator 交互扩展参考 idb / FBSimulatorControl;Runtime 自动下载参考 Apple 官方文档。并非“Xcode 没有可控 API”,而是需要组合生命周期、输入与画面能力。
构建 Simulator .app;自动检查 Xcode、下载 Runtime、创建设备并安装。缺少 Xcode 或尚未授权时仍存在宿主前置条件。
这是方案选择器,不会检测电脑或执行安装。
vphone 是研究虚拟机,不是 Simulator 外壳。
它基于 Apple Virtualization.framework 与 PCC 研究虚拟机基础设施,组合 iPhone 与 cloudOS 固件,修改启动及系统组件,在虚拟机中部署 vphoned。由宿主 CLI 编排,独立的 vphone-vm 负责实际运行。[1]
版本必须固定。调研初次读取未固定版本的网页,返回了与当前快照不同的说明:Homebrew 依赖、-V jb、SSH/VNC。随后下载的固定源码及其中的中英文文档呈现了新行为。该网页结果未绑定历史 commit,差异原因未确认;本文以固定 commit 为准,未固定网页与历史截图仅用于对照。
| 事项 | 未固定网页 / 截图印象 | 固定源码的实际行为 |
|---|---|---|
| 依赖安装 | 安装大量 brew 包、Python venv | 上游文档声明分发 .app 运行时不要求 brew / Python / Xcode,源码也已内置相关组件;干净机分发验收仍待完成。源码构建需完整 Xcode 和 iPhoneOS SDK |
| 固件变体 | less / regular / dev / jb / exp,-V jb | 当前 CLI 仅 JB 主线,create 没有 variant 选项;非交互运行要提供两份固件来源 |
| 远程连接 | 默认 SSH 22222、VNC 5901 | 当前不默认安装 SSH/VNC/包管理器;使用 guest HTTP/WS、宿主 Unix socket |
| create 成功 | 设备已经持续运行 | 首启验证 vphoned ping 后停止验证实例;必须再 launch 才进入持续使用 |
| 进程被 Killed | 直接判定内存耗尽 | 也可能是 AMFI 拒绝带私有 entitlement 的进程;先取证,不能仅凭信号 9 定性 |
创建链路,逐层看成本
固件准备包含解包与 GPU 驱动准备;恢复需要联网获取 Apple restore ticket;CFW 通过宿主挂载磁盘安装,涉及管理员权限。默认创建配置为 8 vCPU、8192 MiB 内存、64 GB 虚拟磁盘。这是源码默认值,不是宿主只要空闲 64 GB 就够的容量结论。解包、缓存、临时磁盘都要计入。64 GB 是稀疏虚拟磁盘的逻辑容量;当前 create CLI 只暴露 disk-size,CPU/内存默认值不能直接通过 create 参数修改。[2]
上游记录两组固件完成过到锁屏及 vphoned ping 的验证;它们是上游证据,不是本次在当前机器上运行的结果,也不代表业务 App 已兼容。[3]
把安装做进产品,而不是写一页前置条件。
目标体验是「打开设备面板 → 自动检查 → 自动准备可完成的部分 → 设备就绪」。主路径不要求用户打开终端、安装 Homebrew、配置 PATH 或逐个复制命令。下面是产品化设计;下载区提供的是开发验证包,两者完成度分别标记。
- 发布端先做重活
CI 固定源码及 Package.resolved,构建完整 runtime .app;记录散列、签名、依赖清单、兼容矩阵。每版在干净物理 Mac 上验证。私有 entitlement 可否正常分发、签名与公证必须实测,不把 ad-hoc 签名等同于常规公证可分发。
- 桌面启动后探测,不先下载
检查 CPU、系统、是否嵌套虚拟化、磁盘容量、当前资源占用与 host preflight。preflight 检查嵌套环境、伴随进程及 entitlement,并探测其 --help 是否被拒绝;不验证 Recovery 配置、固件或真正的 PV=3 建机。通过后仍要验证真实 VM 启动。
- 按需获取内置运行包
默认复用自有兼容运行包,缺失时由安装管理器下载固定版本到暂存目录,校验 SHA-256 和签名,再原子切换版本目录。所有数据放在用户 Application Support 中,不改 shell 配置。
- 固件目录替用户做选择
产品维护已验证的 iPhone/cloudOS 配对清单及摘要;优先使用合法可用的本地缓存,否则后台从明确来源下载。UI 只显示大小、进度和失败原因。离线包只承诺可缓存素材,在线 restore ticket 仍可能必需。
- 单实例创建,失败保留证据
对每台设备加任务锁,串行执行昂贵阶段;记录阶段输入散列、产物与日志。下载可续传,阶段恢复须校验前序产物。上游 create 对同名目录会报错,不能把“重跑 create”称为自动续装。
- 验证后交接给面板
create 完成后单独 launch;等待 health、host ping 与首帧,再进入 Ready。网络恢复后只重试可幂等请求;IPA 安装等变更操作先核实结果,避免重复执行。
哪些真的能自动完成?
| 步骤 | 自动化策略 | 用户侧边界 |
|---|---|---|
| brew / Python / 编译工具 | 运行包由产品预构建;不转嫁给最终用户 | 开发调试包单独需要 Python;源码构建需要完整 Xcode |
| 下载、缓存、解包、建机 | 任务队列、散列校验、进度事件、可恢复检查点 | 磁盘不足或外部服务不可达时展示具体阻断 |
| CFW 管理员权限 | PoC 用上游 --root-popup;生产设计受限权限 helper | 系统认证仍可能需要确认;不收集或保存 sudo 密码 |
| PV=3 / SIP / AMFI | 只检测并报告,不偷偷调整 | 恢复模式设置无法由普通桌面脚本完成;白名单与 build 签名相关,重建后需重新处理 |
| 应用安装与控制 | 上传→安装→查询→启动→前台及截图确认,统一一个操作 | 业务登录、硬件依赖、包兼容性不能承诺自动解决 |
零人工的可行定义:在已准备的受管研究 Mac 上,后续设备创建与使用尽量自动化;在普通未配置 Mac 上,vphone 当前不能满足“用户一次操作也没有”。上游两种宿主方案都涉及 Recovery 配置。严格要求零宿主变更时,应选已具备条件的 Simulator 环境,或由运维预配置的远端物理 Mac 服务。[4]
状态机与更新策略
Unknown → Checking → RuntimeReady → FirmwareReady
→ Creating → Verifying → Stopped → Starting → Ready
任意阶段 → Blocked(明确条件)/ Failed(可诊断)
Ready → Stopping → Stopped
更新:新版本预检 → 新设备验证 → 切换;旧运行包与旧设备保留错误码区分 HOST_POLICY_BLOCKED、RESOURCE_LOW、DOWNLOAD_FAILED、RESTORE_FAILED、GUEST_NOT_READY、APP_INCOMPATIBLE。日志默认本地脱敏保存,导出前排除账户信息、签名证书与应用内容。卸载仅移除本产品管理的 runtime;删除设备数据应作为独立操作。
面板管交互,服务管设备。
未取得实际 Desktop 源码,本方案按 Electron / WebView 工作台假设设计。实现前确认主进程与渲染进程边界,保留现有 UI 框架;不要为了引入虚拟机更换桌面架构。
Renderer / Device Panel
│ 受限 IPC:list / create / launch / stop / install / input
Desktop Main Process
│ 参数校验、任务 ID、取消、授权与目录边界
Device Service(本地进程;普通用户权限)
├── Runtime Manager / Firmware Cache / Job Store
├── Simulator Adapter → simctl + idb 或原生桥
└── VPhone Adapter
├── vphone-cli:生命周期、固件、创建
├── HTTP / WS → VSOCK 1339 → vphoned
└── Unix socket → 截图、tap、swipe、硬件键直接复用的接口
| 用途 | 上游现有能力 | 接入注意 |
|---|---|---|
| 健康与能力 | GET /v1/health、GET /openapi.json | 启动后校验 runtime / daemon 兼容,接口缺失显式降级 |
| 应用与文件 | /v1/apps、/v1/apps/install、/v1/files/content | 本机路径与 guest 路径不同,安装需先上传 |
| 事件与输入 | /v1/events WebSocket、input.touch 等 RPC | 用请求 ID 关联响应;触摸发送 down / move / up;标准化坐标需映射方向与留白 |
| 截图与硬件键 | <bundle>/vphone.sock,JSON 行协议 | 像素坐标;默认响应是缩小灰度 JPEG,不能当高保真录屏 |
HTTP/WS 转发通过 vm launch --api-listen 127.0.0.1:8765 显式启用。上游 API 当前没有认证,所以只能由受控本地服务访问;生产应优先直接封装 VSOCK/IPC,若必须 TCP,应增加代理鉴权、来源验证与绑定地址限制。单加一个代理 token 不会保护仍可被其他本地进程直连的裸端口。渲染器不暴露通用 shell 或任意 icli.execute。[5]
画面嵌入分两步,避免把截图说成视频
PoC:保持上游原生 VM 窗口,面板先提供低频截图预览和操作回执;需要彩色细节时向 Unix socket 发送带受控主机路径的 {"t":"screenshot","path":"/tmp/shot.png"},得到全尺寸截图文件。省略 path 只返回缩小灰度图,不落全尺寸文件。这可验证坐标、任务链与故障处理,不承诺流畅视频。
产品版:扩展宿主帧生产器,将图像通过受控共享内存或编码流送给面板。加入最新帧优先、背压、失焦降帧、断流重连与旋转映射;交互帧率与延迟作为实测指标。上游有本地 .mov 录屏实现,但未发现现成的面板视频流 API。原生 NSView 的跨进程嵌入另做小实验,不将拖入窗口当成稳定方案。[6]
面板只展示用户关心的状态
上方是设备选择与启动/停止;中央是设备画面;下方提供安装应用、Home、截图、诊断。首次安装显示阶段、已下载大小和可解释的阻断原因。默认隐藏固件内部术语;错误详情和版本记录留在“诊断”中。关闭面板是否保留设备运行由明确的会话策略决定,不能丢下不可见后台虚拟机。
能安装 IPA,不代表业务已经可用。
vphone 的应用安装不是 simctl install。源码会在 guest 中解包、重签并注册应用;apps.install 接收的是 guest 文件路径。Desktop 的安装按钮需要封装完整流程。[7]
- 检查安装包:识别 .app / .ipa、目标平台与架构、bundle ID、大小、来源和解包路径;Simulator 构建交给 Simulator,设备构建进入 vphone 兼容验证。
- 上传:流式写入 guest 临时目录;记录文件摘要。不要将宿主
/Users/…/app.ipa直接填进 guest install 请求。 - 安装:调用
apps.install并保留返回值;成功后查询安装列表,验证 bundle ID 和版本,再清理该任务的临时文件。 - 启动:调用
apps.launch,核查前台 bundle ID、进程与截图;如果立即退出,采集 crash 信息,标为启动失败而非安装成功。 - 业务验收:验证测试账号登录、首页、网络和一条核心链路。安装、进程存活、业务可用分别记录。
目标业务 App 目前的结论:待验证。本次没有目标包、签名配置或测试账户,不能确认可运行。商店下载包的加密、签名依赖、Keychain / 推送 / 完整性校验及虚拟环境检测均可能影响结果。首轮使用团队可控的开发 IPA,随后单独验证目标 App。
开源仓库为 MIT 许可;这不等于 Apple 固件、业务包、账户或修改宿主安全设置自动获得组织许可。软件分发、固件来源与研究机准入需要由项目责任方确认。这里没有作出“已符合企业安全规定”的结论。[8]
先找证据,再解释 Killed。
截图能证明进程被终止,不能证明 OOM。退出码 137 或 SIGKILL 只说明进程被信号 9 结束;AMFI、内存压力、主动结束或其他系统策略均需要相应证据。也没有依据把 JB 称作“更轻量的版本”。
| 现象 | 检查 | 应给出的结论与动作 |
|---|---|---|
| 窗口尚未出现就终止 | 先运行 host preflight,结合 amfid / code signing 日志和准确时间、PID | 有拒绝证据才归为 AMFI;近期重建需检查 cdhash。单纯释放内存未必有用 |
| 解包或建机阶段中断 | 可用磁盘、vm_stat、memory_pressure、进程峰值、memorystatus 日志 | 有同一进程内存终止记录才归为 OOM;限并发、减少构建 jobs,并调整容量计划 |
| 恢复阶段失败 | 网络、ticket 请求、固件配对、DFU 与 restore 日志 | 归到对应阶段;先校验产物,不能无限重复整条流水线 |
| 设备启动但无法控制 | daemon 版本、health、socket ping、启动日志 | 区分画面可见与服务 Ready;旧 daemon 不兼容时应重建匹配设备 |
| 应用安装后闪退 | bundle、签名/加密状态、crash log、前台进程 | 报告包兼容或运行问题;不能把每次闪退都归因于虚拟机内存 |
附带脚本的 diagnose 读取本地日志线索,不自动修改系统设置,也不因关键词出现而确认根因。host preflight 的失败也不全是 AMFI:二进制缺失、版本不匹配等仍要保留原始错误。[9]
一个可下载、可审查的调试入口。
交付的是源码锁定的开发 PoC:把预检、准备、创建、启动、API 检查和诊断收在同一个入口。它不是已经签名分发的 Desktop 插件,也不包含 Apple 固件、业务 IPA 或预先修改好的系统镜像。
vphone-local-kit
Python 标准库控制器 + Shell 入口 + 使用说明 + mock 验证。支持 dry-run,不自动变更 SIP / AMFI,不存储管理员密码。
以压缩包内 README 的命令和参数为准。源码绑定 commit,不使用漂移的 main。下载校验见 SHA256SUMS.txt。
脚本与命令清单
| 文件 / 命令 | 已实现内容 |
|---|---|
| vphone-local | macOS Shell 入口,调用 Python 3.9+ |
| vphone_local.py | 标准库控制器:参数数组调用、本地数据隔离、超时及失败日志 |
| doctor | 读取系统、架构、磁盘、内存、SDK 与嵌套环境;按需调用上游 preflight |
| bootstrap | 显式执行时获取固定源码并构建;也可复用已有 CLI |
| create / launch / stop | 本地固件建机、系统认证窗口、前台启动与停止;显式 execute 才执行 |
| health / screenshot / touch | loopback HTTP 健康检查;Unix socket 截图与像素坐标点击 |
| diagnose | 从日志提取候选线索;不把 Killed 直接归因为 OOM |
| tests/test_vphone_local.py | mock 回归:协议、预检、认证参数、版本约束和错误归因 |
尚未实现:可分发 runtime 下载管理、固件清单自动选择/下载、IPA 安装封装、Desktop 面板、视频流、任务断点恢复。这些属于前文产品设计。复用外部二进制时需另核版本;commit 锁定用于源码构建路径。
展开:本地开发调试命令
./vphone-local doctor
./vphone-local bootstrap --fetch-source --dry-run
# 需要完整 Xcode + iOS SDK;获取固定源码并构建
./vphone-local bootstrap --fetch-source --execute
VP="$PWD/upstream/.build/vphone-cli.app/Contents/MacOS/vphone-cli"
./vphone-local --cli "$VP" doctor --preflight
./vphone-local --cli "$VP" create devphone \
--iphone-source /path/to/iPhone_Restore.ipsw \
--cloudos-source /path/to/cloudOS.ipsw --execute
./vphone-local --cli "$VP" launch devphone --execute
# launch 持续占用前台,下面由并行调试进程调用
./vphone-local health
./vphone-local screenshot devphone --output /tmp/devphone.png
./vphone-local touch devphone 645 1398
./vphone-local --cli "$VP" stop devphone --execute上游等价命令:解释实际做了什么
# 在完整 Xcode + iPhoneOS SDK 的构建机上构建固定快照
# 源码实际目录为 Scripts,注意 macOS 大小写敏感卷
zsh Scripts/build.sh
# 以下 VP 指向构建或分发包中的 CLI;数据目录由包装器隔离
VP="/path/to/vphone-cli.app/Contents/MacOS/vphone-cli"
"$VP" host preflight
# 固件来源由产品清单提供;这里为可读的本地占位路径
"$VP" vm create devphone \
--iphone-source /path/to/iPhone_Restore.ipsw \
--cloudos-source /path/to/cloudOS.ipsw \
--root-popup
# create 验证后会停止,必须再启动
"$VP" vm launch devphone --api-listen 127.0.0.1:8765
# launch 是前台持续运行;以下为并行诊断端执行的等价请求
curl --fail http://127.0.0.1:8765/v1/health
curl --fail http://127.0.0.1:8765/openapi.json
"$VP" vm stop devphone本地脚本使用 Python 是为了让开发者直接审查和调试;最终产品使用已内置的桌面运行时或编译后的原生服务,无需用户安装 Python。未将 Python 声称为 macOS 默认可用,也未以自动安装 brew 作为主解决方案。
本次验证边界
已通过 9 项 mock 回归检查,并完成页面桌面/手机、深浅色及交互检查。查看验证记录。
已核对固定源码及宿主环境,脚本验证记录随包提供。当前宿主只有 Command Line Tools,没有完整 Xcode;本次未构建上游 .app、未修改 SIP/AMFI、未下载固件、未创建真实 iOS VM,也未验证目标业务 App。
每个阶段都有可判断的完成条件。
| 阶段 | 交付 | 完成证据 |
|---|---|---|
| P0 / 技术可行性 | 固定版本脚本、1 台研究 Mac、受控开发 IPA | 预检→create→launch→health→首帧→安装→启动,保留版本与日志;三次独立运行复核 |
| P1 / 面板接入 | 设备服务、任务状态、截图/输入、安装进度 | 可从面板完成一条完整链路;坐标正确、失败可诊断、取消后无遗留进程 |
| P2 / 安装产品化 | 签名 runtime、固件清单、缓存、受限权限 helper | 干净已准入宿主安装,无 brew / 终端步骤;中断、磁盘不足、版本回滚演练通过 |
| P3 / 体验与扩展 | 低延迟画面、Simulator adapter;按需远端设备 | 画面/输入延迟、资源占用、断连与隔离实测;不以功能存在代替性能验收 |
建议两周完成 P0/P1 的小范围原型:设备服务与安装链路、面板与画面分别推进;这是在研究 Mac、开发 IPA 与桌面仓库均可用条件下的粗估,P2 的分发和系统准入会影响排期。首要决策不是先画多少按钮,而是团队能否提供适用研究机、是否能产出 Simulator 构建,以及目标包属于何种分发类型。
开发接入前还缺哪些具体材料?
- Desktop 源码位置、技术栈、面板扩展点与已有 IPC 约束。
- 研究 Mac 的系统准入条件、可用磁盘及内存预算。
- 可测试的开发 IPA / Simulator .app、bundle ID 和最小验收路径。
- 产品“无需操作”的定义:是否接受首次系统认证、预配置研究机或远端设备。
这些是进入实机集成阶段的输入,不影响本方案与调试包交付。
从源码到结论,可追溯。
检索日期:2026-09-24。Git 快照 3f7011406722576fb19bffbc8c30d8aa4c4916af。以下路径固定到同一提交;产品设计、性能目标与排期属于本方案建议。
- README、Package.swift、build.sh:当前架构、内置依赖与构建签名流程。
- CreateCLI、CreateOptions、Creator:参数、资源默认值、创建步骤及验证后停止。
- Compatibility:上游验证范围。请区分上游记录与本次实测。
- Host setup、HostPreflight:Recovery、私有 entitlement、AMFI 与预检边界。
- HTTP / WebSocket API、OpenAPI:VSOCK 1339、接口、版本与认证限制。
- HostAutomationServer、ScreenRecorder:JSON 行协议、截图与本地录屏。
- GuestAPI、GuestControl、IPA 安装实现:上传 guest 文件、安装、重签与注册。
- MIT LICENSE:开源仓库许可;不代表其他素材或宿主准入已获授权。
- Troubleshooting、当前中文版说明:故障处理与当前中文文档。
- idb:FBSimulatorControl、idb 仓库:Simulator 控制的开源参考。
- Apple:下载和安装 Xcode 组件:Simulator Runtime 的官方管理方式。