我开发 CoreX,不是为了再做一张“看起来很专业”的仪表盘,而是想回答一个更实际的问题:一台 Mac 此刻为什么变慢、风扇为什么开始工作、内存压力是否已经影响任务,以及这些信息能否在不上传数据的前提下被快速理解。
CoreX 是一款完全在本机运行的原生 macOS 系统监控工具。它使用 Swift 6、SwiftUI 和 AppKit 构建界面,通过 Mach、IOKit、Metal、Foundation 与 Darwin 读取系统状态,覆盖 CPU、单核负载、GPU、内存、磁盘、网络、运行时间和系统热压力。主窗口负责分析,菜单栏负责扫一眼,设置系统负责决定它应该怎样融入日常工作。
下载 CoreX 1.0(macOS 14+,Apple Silicon)
下载 CoreX-1.0-macOS-arm64.zip · 约 2 MB
SHA-256:ae116fe638e81e3b2acfa34dd531ebbe4251bfa2b3cae7074a223136a7ea321a

产品边界:不是“数据越多越好”
系统监控工具很容易陷入两个极端:要么只展示几个百分比,无法解释问题;要么把所有底层指标堆在一起,让用户自己寻找异常。CoreX 采用三层信息架构:
- 概览层:CPU、GPU、内存、磁盘、网络和热状态,几秒内判断机器是否健康。
- 诊断层:每核心负载、P-core/E-core 分组、实时曲线和设备信息,定位瓶颈来自哪里。
- 常驻层:菜单栏只保留最重要的数据,不打开主窗口也能观察变化。
采样和展示也被刻意分开。SystemMonitor 负责产生统一快照,SwiftUI 只消费状态;历史序列保留固定长度,避免曲线无限增长。暂停监控时停止刷新,而不是仅仅停止动画。这个边界让 UI、采集和偏好设置可以独立演进。
Mach / IOKit / Metal / Darwin / Foundation
│
▼
SystemMonitor 采样器
计算差值、归一化、限幅
│
┌─────────┴─────────┐
▼ ▼
当前 Snapshot 固定长度历史序列
│ │
└─────────┬─────────┘
▼
SwiftUI Dashboard + MenuBarExtra
│
▼
AppStorage / 通知 / 登录启动策略
Swift 如何读取 macOS 的真实状态
CPU:比例必须来自两个时刻的差值
CPU 时间是累积计数器,不能把某次读取的值直接当成瞬时利用率。CoreX 通过 Mach 的 host_statistics 和 host_processor_info 读取 user、system、nice、idle ticks,保存上一次快照,再用本次与上次的差值计算:
usage = Δ(user + system + nice) / Δ(user + system + nice + idle)
总 CPU 与逐核 CPU 使用同一计算原则。Apple Silicon 上再结合核心数量,把性能核与能效核分组展示。工程上必须处理首次采样、计数器异常、数组释放和结果限幅,否则启动瞬间或长时间运行后容易出现跳变。
内存:展示压力,而不只展示“已用”
CoreX 通过 host_statistics64 获取 active、inactive、wired、compressed 和 free pages。macOS 会主动利用空闲内存进行缓存,因此“内存占用高”并不必然意味着系统有问题。界面同时提供用量与趋势,把数值放回时间上下文,而不是用一个红色百分比制造焦虑。
GPU:Metal 识别设备,IOKit 尝试读取负载
MTLCopyAllDevices() 用于获取 GPU 名称与设备信息;实时利用率则从 IOKit 的 IOAccelerator 性能统计中读取。需要说明的是,GPU 利用率不是跨所有 macOS 与硬件组合都稳定公开的标准接口:如果驱动没有暴露对应字段,CoreX 会显示不可用,而不是伪造一个零值。
磁盘、网络与热状态
- 磁盘容量使用
URLResourceValues.volumeTotalCapacity与volumeAvailableCapacityForImportantUsage,反映系统认为真正可用于重要任务的空间。 - 网络通过
getifaddrs聚合活动接口字节数,再以采样间隔计算上传、下载速率;需要排除 loopback,并处理接口切换造成的计数重置。 - 热状态使用
ProcessInfo.thermalState。这是 macOS 提供的系统级热压力信号,并非某个传感器的摄氏温度。CoreX 因此使用“正常、较高、严重、危急”表达,不把估算值伪装成精确温度。
所有数据均在本机读取和渲染,CoreX 不需要账户,也不会把监控数据上传到服务器。
为什么选择 SwiftUI,同时保留 AppKit
SwiftUI 非常适合仪表卡片、状态驱动视图、主题和设置表单;但一个成熟的 macOS 工具还需要窗口激活、Dock 策略、应用重开和 About 面板等生命周期控制。因此 CoreX 不是纯 SwiftUI 项目,而是组合使用:
WindowGroup管理主窗口,设置最小尺寸和默认尺寸;MenuBarExtra(.window)提供可交互状态卡;NSApplicationDelegateAdaptor处理关闭最后窗口后是否退出、点击 Dock 图标后恢复窗口;NSApplication.setActivationPolicy在普通应用和仅菜单栏模式间切换;SMAppService管理登录时启动。
这种方式比强行只用一种 UI 框架更符合 macOS 工具的真实需求:SwiftUI 负责声明式界面,AppKit 补齐系统行为。
设置不是装饰,而是产品行为的一部分

CoreX 的设置分为外观、通用、监控、通知、快捷键和关于。重要的不是选项数量,而是每一个选项都真正连接到运行行为:
- 跟随系统、浅色或深色主题,强调色、界面密度、圆角、玻璃材质与动画;
- 登录启动、启动后显示主窗口或仅驻留菜单栏、关闭窗口后是否继续运行;
- 1/2/5 秒刷新间隔、启用的指标、60 秒/5 分钟/15 分钟历史长度;
- 菜单栏显示图标、CPU 或 CPU + GPU;
- CPU、内存、磁盘和热压力阈值通知;
- 打开总览与暂停监控的快捷键。
偏好通过 @AppStorage 持久化,但“保存了值”并不等于“实现了功能”。例如显示 Dock 图标的开关必须调用 activation policy,刷新间隔必须重建采样节奏,关闭窗口后的策略必须进入 App Delegate。开发中我把每个设置都当作一条从 UI 到系统行为的链路来验证。
菜单栏是高频入口

菜单栏状态卡只显示 CPU、GPU、内存和当前运行状态,并提供设置、更新检查和退出。它适合在编译、运行本地模型、视频处理或多任务切换时快速观察资源变化。主界面负责解释,菜单栏负责低打扰感知,两者不应该复制同一套信息密度。
开发与打包环境
项目使用 Swift Package Manager,最低部署目标为 macOS 14,链接 IOKit 与 Metal。开发机应安装版本匹配的 Xcode 或 Command Line Tools:Swift 编译器与 macOS SDK 若来自不同版本,可能出现“SDK 由另一版本 Swift 编译”的错误。可靠的发布流程应固定 Xcode 版本,并在干净环境中构建。
cd MacPulse
./scripts/build-app.sh
open dist/CoreX.app
构建脚本执行 release 编译、组装 .app 目录、生成图标并进行签名。当前下载包为 arm64,使用 ad-hoc 签名,适合直接试用和内部发布;正式面向大量用户时,应改用 Developer ID Application 证书,提交 Apple notarization,并通过 stapler 附加公证票据。
适合哪些 Mac
| 项目 | 当前下载包 |
|---|---|
| 操作系统 | macOS 14 Sonoma 或更高版本 |
| 处理器 | Apple Silicon:M1、M2、M3、M4、M5 系列 |
| Intel Mac | 当前 arm64 包不支持;源码架构可扩展通用包 |
| 网络 | 运行不需要联网;检查更新除外 |
| 数据 | 所有监控数据只在本机处理 |
| GPU 数据 | 取决于系统驱动是否暴露 IOKit 性能字段 |
它尤其适合开发者、本地大模型用户、设计与视频工作者,以及希望长期观察 Mac 资源状态的人。它不适合作为数据中心监控、远程告警或硬件维修诊断工具,也不应替代 Apple Diagnostics。
下载、安装与安全说明
- 下载 CoreX 1.0 并解压。
- 把
CoreX.app拖入“应用程序”目录。 - 首次启动建议右键应用并选择“打开”。如果 Gatekeeper 阻止启动,可前往“系统设置 → 隐私与安全性”确认“仍要打开”。
- 可用下面的命令核对安装包:
shasum -a 256 CoreX-1.0-macOS-arm64.zip
# ae116fe638e81e3b2acfa34dd531ebbe4251bfa2b3cae7074a223136a7ea321a
当前版本没有 Apple 公证,这是公开测试包最需要补齐的发布环节。这个限制必须被明确说明,而不是把 Gatekeeper 提示留给用户猜测。
这次开发留下的几条原则
第一,系统监控的难点不是绘图,而是指标语义。累积值要转换成差值,缺失值要如实表达,热压力不能冒充温度。
第二,原生体验来自行为闭环。窗口、Dock、菜单栏、登录启动和偏好设置只有真正接入生命周期,才算功能完成。
第三,发布链路属于产品。固定工具链、架构标识、签名、公证、哈希校验和下载说明,都应该和代码一起设计。
CoreX 的下一步会聚焦在更可靠的 GPU 兼容性、可诊断的内存压力、进程级资源归因、通用架构包,以及完整的 Developer ID 签名与公证。对一款本机系统工具而言,“可信、准确、低打扰”比不断增加图表更重要。