网络配置,一键切换

IP Switch 是一款原生 macOS 应用:把多套网络配置保存为预设, 在主窗口或菜单栏一键切换系统 IP / DNS。 特权 XPC helper 负责真正修改系统设置,GUI 与 CLI 双形态交付。

网状地球与绿色切换徽章插图

功能特性

为「多环境网络」而生

从预设管理到命令注入防护,每一层都为频繁切换网络的开发者打磨。

🗂️

预设管理

保存多套网络配置:网卡、服务名、手动 / DHCP、IP、掩码、网关、DNS,增删改查。

⚡

一键切换

点击卡片或菜单栏项即可切换,可选切换前确认,减少误触。

🍎

菜单栏常驻

NSStatusItem 动态预设菜单,与主窗口配合,随手可达。

🔄

启动状态校正

以记忆的激活预设为锚校验当前网卡配置,被外部更改则提示,恰好匹配则自动采纳。

⌨️

CLI 工具

status / active 子命令,支持 --json,可嵌入 shell 工作流。

🔐

特权 helper

XPC LaunchDaemon 执行需要 root 的写操作;免签名脚本安装,免费 Apple ID 即可真机部署。

🔌

系统集成

登录时启动(SMAppService),切换完成后本地通知(UNUserNotificationCenter)。

🛡️

命令注入防护

仅调用绝对路径 /usr/sbin/networksetup;IP / 掩码 / 网关 / DNS 严格 IPv4 校验。

图形界面

主窗口与菜单栏,两处都能切换

SwiftUI 原生界面。预设以卡片排布,激活状态一眼可见;点开关即刻切换,也可常驻菜单栏,在任意应用间快速操作。

IP Switch
网络配置切换

预设配置

0 套

👆 可交互高保真原型 · 点开关切换预设、✏️ 编辑、⚙️ 设置(数据仅保存在浏览器本地,不影响系统)

🍎

菜单栏常驻

NSStatusItem 动态列出全部预设,不打开主窗口也能一键切换,切换后用通知确认生效。

🔄

启动状态校正

以记忆的激活预设为锚校验当前网卡:被外部更改则提示,恰好匹配则自动采纳。

🔔

切换即时反馈

激活态开关与卡片立即响应,配合 Toast 与可选系统通知,成功或失败都有明确反馈。

命令行

命令行切换,支持脚本自动化

CLI 嵌入 App bundle,也可单独构建;退出码语义明确,适合接入 shell 工作流与自动化。

终端 — ipswitch-cli
$ ipswitch-cli status
预设:
  ● 公司内网   Wi-Fi · 手动 192.168.1.23/24 · 网关 192.168.1.1
  ○ 家庭宽带   Wi-Fi · DHCP
  ○ 实验室静态  USB 10G · 手动 10.0.4.12/24
激活:公司内网

$ ipswitch-cli active # 支持模糊匹配
公司内网(Wi-Fi · 手动)

$ ipswitch-cli status --json # 供脚本解析
{ "presets": [...], "activeId": "..." }

退出码 0 · 成功

  • 命令执行成功,输出按预期返回

退出码 1 · 一般失败

  • 参数错误 / 未匹配 / 命令失败 / 授权取消

退出码 2 · 内部错误

  • state 解析失败等不可恢复错误

系统架构

四个 target,一条特权链路

GUI、CLI 与特权 helper 共享核心源码;应用进程只读,写操作经 XPC 送达 root 层的 LaunchDaemon。

IP Switch · 系统架构
IP Switch · 系统架构 由 Archify 生成的架构图。 ipswitch-cli · status · active --json · ipswitch.app(GUI 进程) ipswitch-cli status · active --json PresetStore · state.json 原子读写 · ipswitch.app(GUI 进程) PresetStore state.json 原子读写 HelperInstaller · 免签名脚本安装器 · ipswitch.app(GUI 进程) HelperInstaller 免签名脚本安装器 SwiftUI 界面 · 主窗口 · 菜单栏 NSStatusItem · ipswitch.app(GUI 进程) SwiftUI 界面 主窗口 · 菜单栏 NSStatusItem AppViewModel · @MainActor 唯一协调者 · ipswitch.app(GUI 进程) AppViewModel @MainActor 唯一协调者 PresetApplyExecutor · helper 优先 · 失败回退 · ipswitch.app(GUI 进程) PresetApplyExecutor helper 优先 · 失败回退 HelperClient · NSXPCConnection · ipswitch.app(GUI 进程) HelperClient NSXPCConnection ipswitch-helper · 特权 LaunchDaemon (root) · Root · launchd ipswitch-helper 特权 LaunchDaemon (root) SystemIntegration · SMAppService · 本地通知 · ipswitch.app(GUI 进程) SystemIntegration SMAppService · 本地通知 NetworkService · 网卡枚举 · 读取 · 启动校正 · ipswitch.app(GUI 进程) NetworkService 网卡枚举 · 读取 · 启动校正 CommandRunner · 只读 Process · 提权 AppleScript · ipswitch.app(GUI 进程) CommandRunner 只读 Process · 提权 AppleScript networksetup · /usr/sbin/networksetup · Root · launchd networksetup /usr/sbin/networksetup 读取 state.json 点击切换 · 编辑预设 读写 state performSwitch 枚举 · 启动校正 登录项 · 通知 只读查询 回退提权 applyPreset 请求 XPC mach service 白名单命令组 提权执行 launchctl bootstrap ipswitch.app(GUI 进程) Root · launchd 图例 前端 后端 数据库 云服务 安全 外部系统

交付形态

  • ipswitch.app:SwiftUI 主窗口 + 菜单栏 NSStatusItem
  • ipswitch-cli:嵌入 App bundle,支持 --json 输出
  • helper 以 LaunchDaemon 常驻,root 权限执行写操作

切换主路径

  • AppViewModel → PresetApplyExecutor → HelperClient
  • XPC mach service 送达特权 helper
  • helper 拼装 networksetup 命令组并执行

安全边界

  • 仅调用绝对路径 /usr/sbin/networksetup
  • IP / 掩码 / 网关 / DNS 严格 IPv4 校验
  • helper 不暴露任意 shell 或文件写入原语

切换工作流

从点击到生效的完整旅程

触发、探测、特权执行、反馈收尾四阶段;helper 不可用时自动回退,每条失败路径都有明确反馈。

IP Switch · 预设切换工作流
IP Switch · 预设切换工作流 由 Archify 生成的工作流图。 01 / 用户交互 02 / ipswitch.app 03 / 特权层 (root) EX / 异常与回退 触发 探测与分发 特权执行 反馈收尾 触发切换 · UI · 菜单栏 · CLI · 用户交互 › 触发 触发切换 UI · 菜单栏 · CLI 确认弹窗 · 设置可关闭 · 用户交互 › 触发 确认弹窗 设置可关闭 授权取消 · 已取消 Toast · 用户交互 › 特权执行 授权取消 已取消 Toast Toast · 本地通知 · 可选通知 · 用户交互 › 反馈收尾 Toast · 本地通知 可选通知 performSwitch · AppViewModel · ipswitch.app › 触发 performSwitch AppViewModel helper 健康探测 · healthCheck · ipswitch.app › 探测与分发 helper 健康探测 healthCheck XPC 下发预设 · HelperClient · ipswitch.app › 探测与分发 XPC 下发预设 HelperClient AppleScript 回退 · runPrivilegedScript · ipswitch.app › 特权执行 AppleScript 回退 runPrivilegedScript 更新激活态 · 持久化 · state.json 原子写 · ipswitch.app › 反馈收尾 更新激活态 · 持久化 state.json 原子写 白名单校验拼装 · CommandBuilder · 特权层 (root) › 特权执行 白名单校验拼装 CommandBuilder networksetup 执行 · IPv4 + DNS 命令组 · 特权层 (root) › 反馈收尾 networksetup 执行 IPv4 + DNS 命令组 失败 Toast · 退出码 1 · 异常与回退 › 特权执行 失败 Toast 退出码 1 白名单命令组 确认 命令失败 成功 用户取消授权 提权执行 发起切换 不可用 · 超时 健康 Toast · 通知 点击预设 XPC applyPreset 图例 用户界面 Agent 逻辑 策略 外部系统

一键切换主路径

  • UI / 菜单栏触发,可选确认弹窗
  • helper 健康时走 XPC 特权通道
  • 成功后原子持久化并反馈 Toast

回退与异常

  • helper 不可用回退 AppleScript 提权
  • 用户取消授权 → 已取消 Toast
  • 命令失败 → 失败 Toast(退出码 1)

快速构建

三条命令,即刻上手

macOS 26.5+(Apple Silicon)、Xcode 16+、Swift 5.0。构建与运行无需 Developer ID——helper 采用免签名安装。

构建 App(含 CLI 与 helper)

# Debug 构建(App + CLI + helper,helper 与 CLI 嵌入 App bundle)
xcodebuild -project src/ipswitch/ipswitch.xcodeproj \
  -scheme ipswitch -configuration Debug \
  -derivedDataPath src/ipswitch/build build

# Release 构建(分发用)
xcodebuild -project src/ipswitch/ipswitch.xcodeproj \
  -scheme ipswitch -configuration Release \
  -derivedDataPath src/ipswitch/build build

只构建 CLI / 跑测试

# 产物:src/ipswitch/build/Build/Products/Debug/ipswitch-cli
xcodebuild -project src/ipswitch/ipswitch.xcodeproj \
  -target ipswitch-cli -configuration Debug \
  -derivedDataPath src/ipswitch/build build

# 跑单元测试
xcodebuild -project src/ipswitch/ipswitch.xcodeproj \
  -scheme ipswitch -configuration Debug \
  -derivedDataPath src/ipswitch/build test
构建产物位置
ipswitch.appsrc/ipswitch/build/Build/Products/{Debug,Release}/ipswitch.app
App 主二进制ipswitch.app/Contents/MacOS/ipswitch
CLI 二进制(嵌入 App)ipswitch.app/Contents/MacOS/ipswitch-cli
特权 helper(嵌入 App)ipswitch.app/Contents/Library/LaunchServices/ipswitch-helper