每次切环境,手动改 Scheme、换设备、再给 App 传一遍启动参数,点几次就烦了。说实话,手动切几次还行,人一多就乱了。更麻烦的是,同事拉下代码之后,每个人选中的 Scheme 和设备还不一样,复现问题时先要确认半天「你跑的是哪个配置」。这篇讲 VS Code 调试 iOS 怎么把这些固定下来:用
KXApp 的 launch.json 把 Scheme、设备、启动参数和环境变量写进配置,再按场景拆成多套。

先把一份能直接跑的配置摆出来:
1{ 2 "version": "0.2.0", 3 "configurations": [ 4 { 5 "type": "kxapp", 6 "request": "launch", 7 "name": "kxapp: Staging", 8 "scheme": "MyApp", 9 "configuration": "Debug",10 "device": "iPhone 15",11 "build": true,12 "args": ["-env", "staging"],13 "env": { "API_BASE_URL": "https://staging.example.com" }14 },15 {16 "type": "kxapp",17 "request": "attach",18 "name": "kxapp: Attach",19 "pid": 1234520 }21 ]22}
文件放在项目根目录的
.vscode/launch.json。保存之后,VS Code 调试面板的配置下拉框里就会出现这两项,选哪项就跑哪套,不用每次手动点 Scheme 和设备。launch.json 是 VS Code 的调试配置文件,不是插件独有的格式;
type 填
kxapp,调试器就会接管。
scheme 是要构建运行的 Scheme,
configuration 是 Debug、Release 或者工程里自定义的构建配置。这两个名字都得和 Xcode 工程里的一致,拼错一个字母,启动时就会报找不到。
device 填模拟器或真机的 UDID,也可以填名称。名称方便,但同名的模拟器不止一台时容易选错嘛;团队共用配置的话,写 UDID 更稳。模拟器名称在 Xcode 的 Devices and Simulators 里能看到,改过名字的话以新的为准。
scheme、
configuration、
device 不填的时候,就用状态栏里当前选中的那一套;
build 不填默认 true。
build 控制启动前要不要先构建,默认是 true。改成 false 就直接用上一次的产物,适合「只改了一点配置、不想等编译」的场景;前提是之前真的构建过,否则没有产物可装。
| 字段 | 作用 | 不写时 |
|---|---|---|
scheme |
要构建运行的 Scheme | 用状态栏当前选中的 |
configuration |
Debug、Release 或自定义配置 | 用当前选中的 |
device |
模拟器或真机的 UDID / 名称 | 用当前运行目标 |
build |
启动前是否先构建 | true |
args |
传给 App 的启动参数 | 空 |
env |
给 App 的环境变量 | 空 |
pid |
attach 时要附加的进程 ID | 从运行中的 App 里选 |
args 是启动参数,传进去就是命令行参数;
env 是环境变量,两个都直接传给 App,App 里读的地方不一样;用
ProcessInfo 读环境变量、用
CommandLine.arguments 读启动参数,和 Xcode Scheme 里填的是一回事。常见的用法是切环境:
args 里放
-env staging,
env 里放
API_BASE_URL,App 启动时读
ProcessInfo 就能拿到,不用在代码里硬编码,也不用每次手动改。
其实多套环境就多写几份配置,名字起清楚,比如
kxapp: Staging、
kxapp: Prod,调试面板里选一下就能切。比起每次改代码里的常量,配置文件的好处是改动集中、能提交到 git,团队里谁拉下来都是同一套。
别把密钥、token 这类东西明文写进 launch.json。它可以提交到仓库,敏感值放本地环境变量或者不进版本库的配置文件里。
request: "launch" 是启动一个新的调试会话:按配置构建、安装、启动、附加调试器。
build: true 会先编译,
build: false 跳过编译,直接装上一次的产物。
request: "attach" 是接管一个已经在运行的 App,不构建、不安装,只把调试器接上去。在
KXApp 里,命令面板跑「附加到运行中的 App…」,从列表里按名称、pid 或 bundle id 挑一个;
pid 可以不写,不写就现场选。断开之后 App 继续跑,不会被顺手杀掉;这一点和 launch 停止时默认杀 App 不一样。
什么时候用 attach 呢?App 已经通过 Xcode 跑起来了,或者你想保留现场、只补一个断点看看,这时候 attach 比重新跑一遍省事,反正我是这么干的。反过来说,代码改过、需要重新编译,还是得走 launch。attach 适合调试启动后才会出现的状态,比如登录之后、进到某个页面;launch 每次从冷启动开始,有些状态不好复现。
一个项目里放三四份配置很正常:本地模拟器一套、真机一套、连测试环境一套、attach 一套。名字别起得太像,
kxapp: Staging 和
kxapp: Staging iPhone 这种,过两天自己都分不清,挺折腾的。配置多了之后,可以在 name 里带上环境和设备,比如 Staging iPhone 15,一眼能看出用途。
配置之间可以只差一两个字段,比如设备不同、环境变量不同。复制一份改几行,比每次手动切快得多。VS Code 的调试下拉框会把所有配置列出来,选好之后按 F5 就跑,不用记住每个字段。
设备名找不到。 模拟器改名、删掉,或者真机没连上,
device 里的名字就对不上了。换成 UDID,或者先刷新设备列表再跑。
Scheme 或 configuration 拼错。 名字必须和工程里完全一致,大小写也算。不确定就回 Xcode 的 Scheme 编辑器里看一眼。
build 设成 false,但没有产物。 跳过构建之后没有可安装的包,启动会失败,这点挺坑。先跑一次带 build 的配置,再切回来。
launch.json 的 JSON 语法也要检查,少个逗号、多个括号,VS Code 会直接报解析错误,跑不起来(别问我怎么知道的)。
attach 的 pid 过期。 App 重启之后 pid 会变,写死的旧 pid 接不上。把
pid 去掉,让它从运行中的 App 里选。
停止调试后 App 被杀了。 默认行为是停止时结束 App,和 Xcode 一致;想让它留在设备上,把
kxapp.debug.killAppOnStop 关掉。
改了代码,点调试工具栏的「重启」没效果。 「重启」只重启调试会话,不重新编译。改完代码要重新走一次 launch,或者按 Cmd+R。
真机第一次调试慢,不一定是配置的问题。手机升级系统之后,先用 Xcode 的 Devices and Simulators 连一次这台设备,等它准备完,后面停断点就快了。
launch.json 管的是「这次调试怎么跑」:用哪个 Scheme、哪个配置、哪台设备、带什么参数。Scheme 本身的构建目标、签名、测试动作,还是在 Xcode 的 Scheme 编辑器里配。如果 Scheme 本身有问题,先在 Xcode 里跑一遍确认;它不会替你修 Scheme。两边不是替代关系:Xcode 是工程配置的源头, KXApp 把调试入口搬到了 VS Code 里。
同一个工程可以两边同时开,构建产物也是共用的。Xcode 里跑过的,切到 VS Code 不用重新编译;反过来也一样。对团队来说,谁习惯哪个编辑器就用哪个,工程文件不用改,也不用为了统一工具去迁移项目。
顺序可以这么来:先在 Xcode 里确认 Scheme 和构建配置的名字,回到 VS Code 写一份最小的 launch.json,只填
type、
request、
scheme、
device,跑通一次;再把
args、
env 加上,切成两套环境;再补 attach 配置,专门用来接管已经在跑的 App。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047459/viewspace-3187044/ ,如需转载,请注明出处,否则将追究法律责任。