常见的假设是:远程桌面会话会把整套开发环境搬到你的笔记本上。它搬过去的只有屏幕、键盘和鼠标,仅此而已。iPhone 必须连到运行 Xcode 的那台 Mac,而这是一条独立连接,有自己的信任、传输与权限要求。下面的一切都源于这个区分,而多数失败的配置正是这里白白耗掉半天。

误区:远程控制会把设备一起搬过去

远程桌面软件转发的是画面和输入流,在良好连接下确实像 Mac 就在眼前。但它不转发 USB,也不会把手机放进 Mac 的网络。会话终止于 Mac 的桌面,接下来 Xcode 要按自己的规则去找设备。以为手机会跟着像素一起过去,是这种安排里最常见的错误。

两条连接彼此独立,一条可以完美无缺,另一条却根本不存在。修好桌面会话,对设备那条路毫无帮助。

在配置任何东西之前,先确定手机物理上在哪里

如果手机就放在 Mac 旁边,那就在本地做常规配置:信任这台电脑、在设备上打开开发者模式,并在你坐在机器前时确认 Xcode 能构建并运行到它。此后远程桌面只是操控一条已经能跑通的流程。这是最省事的安排,硬件允许时就应该选它。

如果手机跟着你走、Mac 留在办公室,那么 Mac 需要一条受支持的路径通往那台设备。VPN 只提供两端之间的网络路由,别的什么都不提供:配对、开发者模式、签名身份和设备注册仍然是各自独立的要求。把隧道当成栈里的一层,而不是连接本身。

把这两种安排中你所处的那一种写下来。后面每一项检查都依赖它,混为一谈只会得到不可能奏效的修法。

把发现和传输当成两个不同的问题

Xcode 通过局域网里的 Bonjour 找到已配对的无线设备,也可以通过 Connect via IP Address 直达已知地址上的设备。这是两套机制,故障模式也不同。列表里从不出现、和出现了但连不上,不是同一个症状,尽管两者读起来都像手机丢了。

改动任何东西之前先查广播:dns-sd -B _apple-mobdev2._tcp 会列出已配对手机在本地链路上发布的服务。如果什么都没有,说明坏的是发现这一层,只剩按地址连接这一条路。如果服务出现而 Xcode 仍然连不上,说明发现是好的,失败的是传输或信任关系。

Apple 关于无线设备的帮助同时涵盖同一网络的要求和按地址操作的流程,所以要对照你实际安装的版本去读,而不是照搬从旧版本记下来的菜单路径。底下的机制没变,菜单标签也会在 Xcode 各版本之间挪位置。

检查 Mac 从它所在的位置能看到什么

枚举要在 Mac 上跑,而不是在你的笔记本上,因为需要设备的是 Mac。xcrun devicectl list devices 打印 Xcode 能到达的设备,system_profiler SPUSBDataType 显示物理上接了什么。出现在第二份列表里却不在第一份里的手机,是已连接但未配对,那是信任问题,不是网络问题。

xcrun devicectl list devices
system_profiler SPUSBDataType | grep -i iphone
xcrun devicectl device info DEVICE_UDID

如果设备在另一个子网,先确认 Mac 能到达手机公布的地址,并记住 link-local IPv6 地址只在一个链路上有效,无法跨隧道路由。这就是单靠 VPN 很少能让远程手机出现的原因:设备对外宣告的地址只在它自己那一段里有意义。

Apple 技术说明 TN3158 指出,从 15 版本起,Xcode 通过基于 link-local IPv6 构建的网络接口与有线设备通信,因此本地过滤即使对物理插着的手机也会造成干扰。这类情况应上报给负责过滤策略的人,而不要自己去关掉过滤。

用构建来证明,而不是用设备图标

列表里的设备条目、工具栏上的绿点、成功的配对提示,都只是中间观察。只有当 Xcode 安装了被允许的构建、调试器挂上设备上运行的进程时,流程才算被证明。

整套步骤都在 Mac 上执行。xcrun devicectl device install app --device DEVICE_UDID build/MyApp.app 不经过 IDE 就能安装,从而把 Xcode 界面问题和设备通路问题分开。然后启动应用并接上控制台。如果命令行安装能通而 IDE 不通,剩下的故障在 scheme 或签名配置里,而不在网络。

把安排收窄:一个被授权的开发者、一台已注册的 Mac、一台设备,以及随会话结束而终止的访问。安排结束时收回凭据。如果手机干脆可以留在 Mac 旁边,就选那种,因为最简单的受支持路径,剩下的可调试层次最少。

相关文章