news 2026/9/28 20:16:51

从MVVM到Provider注册表:Claude Usage Tracker用量追踪架构深度解析完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从MVVM到Provider注册表:Claude Usage Tracker用量追踪架构深度解析完整指南

从MVVM到Provider注册表:Claude Usage Tracker用量追踪架构深度解析完整指南

【免费下载链接】Claude-Usage-TrackerNative macOS menu bar app for tracking Claude AI usage limits in real-time. Built with Swift/SwiftUI.项目地址: https://gitcode.com/gh_mirrors/cl/Claude-Usage-Tracker

Claude Usage Tracker是一款原生 macOS 菜单栏应用,用 Swift/SwiftUI 构建,能够实时追踪 Claude AI 用量限制(5 小时会话窗口与每周限额),并以多种图标风格呈现在菜单栏中。本文带你深度解析它的MVVM 架构与Provider 注册表设计,看看一个"看起来不大"的菜单栏工具,如何用清晰的工程结构支撑起多服务商(Anthropic、OpenAI Codex)扩展能力。

🧭 项目全景:一个菜单栏 App 的核心能力

对普通用户来说,Claude Usage Tracker 解决的是一个问题:额度还剩多少,还剩多久重置。它把答案直接放在 macOS 菜单栏上:

  • 📊 实时显示 5 小时会话窗口与每周用量百分比,支持电量条、进度条、百分比、圆环等多种图标风格
  • 👤 多 Profile 管理,支持 Anthropic 与 OpenAI Codex 双服务商
  • 🔔 接近额度上限时推送通知,附带用量历史图表与 CSV 导出
  • 📍 Notch HUD:在刘海区域显示 Claude Code 实时会话状态

上面这张图展示的就是它引以为傲的Navbar Icon Styles(彩色与单色两种变体)。图标渲染由 MenuBarIconRenderer.swift 完成——注意,渲染逻辑被单独抽成一个 Renderer 文件,而不是混在视图代码里,这正是后文要讲的"视图保持愚蠢"原则的体现。

🏛️ MVVM 四层分工:谁负责什么

项目在 CONTRIBUTING.md 中明确声明遵循MVVM(Model-View-ViewModel)模式,整个仓库的目录结构就是这张架构图:

层目录职责
Model(模型)Claude Usage/Shared/Models/纯 Swift 数据结构,零 UI 依赖
View(视图)Claude Usage/Views/、Claude Usage/MenuBar/SwiftUI 视图,只负责展示
ViewModel(视图模型)MenuBarManager.swift业务逻辑与状态中枢
Service(服务)Claude Usage/Shared/Services/API 请求、Keychain、通知等系统交互

Model 层:一个 Struct 统一所有服务商的数据

所有服务商的用量最终都被映射到同一个结构体 ClaudeUsage.swift:百分比 + 重置时间作为各服务商的"最大公约数",Token 数、计划类型、余额等字段则按需提供。这种统一数据契约是整套架构的基石——UI 永远只认识ClaudeUsage,从不知道数据来自 Anthropic 还是 Codex。

ViewModel 层:MenuBarManager 是应用的心脏

MenuBarManager.swift(近 1900 行)是整个应用的"大脑"。它作为ObservableObject对外暴露一组@Published状态:

@Published private(set) var usage: ClaudeUsage = .empty @Published private(set) var isRefreshing: Bool = false @Published private(set) var hasCredentialError: Bool = false

它还统一管理刷新定时器、多 Profile 切换、弹窗(Popover)生命周期、深色模式图标缓存等细节。而 App 的启动流程则由 AppDelegate.swift 编排:隐藏 Dock 图标(NSApp.setActivationPolicy(.accessory))、加载 Profile、决定是否弹出设置向导……入口文件 ClaudeUsageTrackerApp.swift 甚至只有十几行——因为这是纯菜单栏应用,默认不创建任何窗口。

View 层:让视图保持"愚蠢"

打开 PopoverContentView.swift 你会发现,SwiftUI 视图通过属性包装器订阅 ViewModel 状态:

@ObservedObject var manager: MenuBarManager @StateObject private var profileManager = ProfileManager.shared

视图本身不做任何网络请求或业务判断,只把manager.usage画出来。配合 SettingsView.swift 等设置界面,形成了"状态变化 → 自动刷新 UI"的单向数据流。

🔌 Provider 注册表:多服务商扩展的关键设计

如果说 MVVM 解决的是"代码怎么分层",那么Provider 注册表(ProviderRegistry)解决的就是"功能怎么扩展"——这是整个架构中最精彩的设计。

一个唯一的"接缝"

ProviderRegistry.swift 的文件头注释写得很直白:

The single seam between the app and its usage providers.(App 与其用量服务商之间的唯一接缝)

整个应用从不出现provider == .anthropic这种硬编码判断。UI 和服务层只通过两个入口获取服务商相关信息:

  1. descriptor(for:)—— 获取声明式的"事实":品牌名、Logo、状态页 URL、能力开关
  2. service(for:)—— 获取负责拉取用量的服务实例

描述符 + 能力开关:用数据代替 if-else

ProviderDescriptor.swift 定义了ProviderCapabilities能力标志:tokenCounts(是否报告 Token 数)、perModelBreakdown(是否有分模型明细)、consoleBilling(是否有计费 API)、cliAccountSync(是否可同步本地 CLI 账号)……

以 Codex 为例,它不报告 Token 数,于是tokenCounts: false——菜单栏的 Token 指标自动隐藏,CSV 导出自动省略 Token 列,图标自动回退到百分比显示。所有这些"隐藏行为"都不需要写任何if provider == .codex,而是由数据驱动。

协议契约:UsageProviderService

每个服务商都实现 UsageProviderService.swift 协议,只需回答三个问题:有没有凭证?怎么拉取用量?活动 Profile 是否允许更宽的认证链(如 Anthropic 的 Keychain CLI 回退)?调用方永远依赖协议,而非具体实现类——这是典型的面向接口编程 + 依赖倒置。

服务商的具体实现按目录隔离:AnthropicUsageProvider.swift 与 CodexUsageProvider.swift,各自带独立的认证服务和 API 客户端。

🛠️ 这套架构对贡献者意味着什么?

docs/ADDING_A_PROVIDER.md 给出了新增加盟服务商的 10 步清单:加一个枚举 case、建一个目录、注册一条描述符与一条服务、配好能力开关、补齐凭证 UI 与本地化……最关键的是文末那句承诺:

What you should NOT need to touch:MenuBarManager、ProfileManager、PopoverContentView、SetupWizardView等核心文件无需修改。

也就是说,扩展是纯增量的(additive)——新增一个服务商就像插一块新板卡,而不是给主板动手术。Codex 的实现(Shared/Services/Providers/Codex/)就是官方参考实现,配套的 CodexProviderTests.swift 展示了 fixture 驱动的容错解码测试写法。

📚 新手阅读源码的路径建议

按这个顺序读,能最快建立整体认知:

  1. 入口:ClaudeUsageTrackerApp.swift → AppDelegate.swift,理解"菜单栏应用没有窗口"这件事
  2. 数据契约:ClaudeUsage.swift → Provider.swift
  3. 状态中枢:MenuBarManager.swift,重点看@Published属性与 Combine 观察者
  4. 注册表:ProviderRegistry.swift → ProviderDescriptor.swift
  5. 扩展规范:docs/ADDING_A_PROVIDER.md,动手前的必读清单

存储层同样值得翻一翻:DataStore.swift 负责 UserDefaults 持久化,ProfileStore.swift 管理多 Profile,而敏感凭证则交给 KeychainService.swift 安全保管——分层清晰,各司其职。

✅ 小结

Claude Usage Tracker 的架构可以浓缩成三句话:

  • MVVM 分层:Model 纯数据、View 纯展示、MenuBarManager 当状态中枢、Service 管系统交互
  • 统一数据契约:所有服务商的用量都映射为ClaudeUsage,UI 不感知来源
  • Provider 注册表:描述符声明"是什么",协议约定"怎么取",能力开关驱动"显不显示",让多服务商扩展成为纯增量操作

对想学习 Swift/SwiftUI 工程实践的开发者来说,这是一个小而美的范本:没有重型框架,只有清晰的分层、接口和约定。想深入了解项目背景与贡献流程,可以参考 README.md 与 CONTRIBUTING.md。

【免费下载链接】Claude-Usage-TrackerNative macOS menu bar app for tracking Claude AI usage limits in real-time. Built with Swift/SwiftUI.项目地址: https://gitcode.com/gh_mirrors/cl/Claude-Usage-Tracker

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 20:16:39

真空共晶焊接空洞率偏高?青岛真空共晶机公司推荐排查思路

焊接面空洞率从3%跳到12%、瓦片TR组件垂直互联真空共晶焊接的互连柱出现裂纹、同一炉产品批次一致性忽好忽坏——这三类异常占了我这些年处理过的真空共晶问题的七成以上。多数时候设备没坏,问题出在真空度、升温曲线、冷却段这三个环节中的一个。先做空洞率分布测试…

作者头像 李华
网站建设 2026/9/28 20:16:19

我对等保2.0的理解

等保2.0即网络安全等级保护2.0,是《网络安全法》规定的基础性网络安全制度。它将系统划分为5个保护等级,核心框架为一个中心,三重防护,防护思路从静态被动转为动态主动的全生命周期防护。保护对象覆盖传统系统及云、大数据、物联网…

作者头像 李华
网站建设 2026/9/28 20:16:19

HTML——庞杂的表单控件元素(一)

庞杂的表单控件元素1、先从元素说起1.1、<form>元素的行为与特征1.1.1、submit事件与submit()方法1.1.2、requestSubmit()方法1.1.3、submitter属性1.1.4、formdata事件1.1.5、reset方法和事件1.1.6、method"dialog"1.1.7、表单元素的关联性1.2、并不简单的<…

作者头像 李华
网站建设 2026/9/28 20:14:50

国内高校学生常用的AI论文网站有哪些?

国内高校学生常用的 AI 论文工具&#xff0c;以本土化全流程产品为主&#xff0c;结合通用大模型与专业辅助功能&#xff0c;覆盖选题、框架搭建、初稿撰写、语言润色、降重处理、查重检测及格式排版等关键环节&#xff0c;以下是主流工具详解与对比&#xff1a;一、本土全流程…

作者头像 李华