关于 swiftui-expert-skill
面向编码 Agent 的 SwiftUI 技能,涵盖代码实现、审查、性能改进和 Instruments 跟踪分析,并提供 API 指引与主题参考。
主要功能
- 01SwiftUI 实现与审查指引
- 02过时 API 查询与迁移
- 03性能和状态管理实践
- 04Instruments 跟踪录制与分析
- 05按主题路由参考文档
适用场景
- 01审查 SwiftUI 代码正确性
- 02实现 SwiftUI 功能
- 03通过跟踪排查性能问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ avdlee/ swiftui-agent-skill --skill swiftui-expert-skill安装后在 Claude Code 中输入/swiftui-expert-skill确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/logo.svgreferences/accessibility-patterns.mdanimation-advanced.mdanimation-basics.mdanimation-transitions.mdcharts-accessibility.mdcharts.mddocument-apps.mdenvironment-patterns.mdfocus-patterns.mdimage-optimization.mdiphone-duo.mdlatest-apis.mdlayout-best-practices.mdliquid-glass.mdlist-patterns.mdlocalization.mdmacos-scenes.mdmacos-views.mdmacos-window-styling.mdmodifier-patterns.mdperformance-patterns.mdpreviews.mdscroll-patterns.mdsheet-navigation-patterns.mdsoft-deprecation.mdstate-management.mdstyled-text-editing.mdtext-patterns.md详细介绍
SwiftUI 专家技能
操作规则
- 将每种
View类型视为失效边界:只向其提供读取的数据,并将频繁变化的依赖项放在受影响的最小子树附近 - 编写、审查或迁移 API 用法时,查阅
references/latest-apis.md;只查找与任务相关的 API - 将彻底弃用的 API 替换为现代等效方案。开发功能时,标记软弃用的 API 并保留原样(参见
references/soft-deprecation.md) - 优先使用原生 SwiftUI API,而非通过 UIKit/AppKit 桥接,除非确有必要
- 注重正确性和性能;不要强制采用特定架构(MVVM、VIPER 等)
- 鼓励将业务逻辑与视图分离,以便测试,但不强制规定分离方式
- 遵循 Apple 人机界面指南和 API 设计模式
- 仅在用户明确要求时采用 Liquid Glass(参见
references/liquid-glass.md) - 将性能优化作为建议,而非要求
- 对特定版本的 API 使用
#available检查,并提供合理的回退方案 - 对于布局和渲染输入,在使用该值的 SwiftUI 视图附近读取;不要用进程级全局屏幕状态替代
任务工作流
审查现有 SwiftUI 代码
- 阅读待审查代码,并确定适用的主题
- 标记已弃用的 API(与
references/latest-apis.md对照);替换彻底弃用的 API,并标记软弃用的 API,除非用户要求迁移,否则不要重写 - 针对每个相关主题运行下方的主题路由器
- 验证特定版本功能的
#available检查和回退路径 - 对于大范围代码库审查,先确定较小的重点区域,并逐一呈现;如果用户要求审查整个代码库,则将其拆分为 TODO 列表
改进现有 SwiftUI 代码
- 根据主题路由器中的主题审查当前实现
- 将彻底弃用的 API 替换为
references/latest-apis.md中的现代等效方案;标记软弃用的 API,并且在开发功能时不要重写 - 重构热点路径,减少不必要的状态更新
- 将复杂的视图主体提取为独立子视图
- 遇到
UIImage(data:)时,建议对图像进行降采样(可选优化,参见references/image-optimization.md)
实现新的 SwiftUI 功能
- 先设计数据流:确定哪些状态由自身持有,哪些状态由外部注入
- 以优化差异比对为目标组织视图(尽早提取子视图)
- 使用正确的动画模式(隐式动画与显式动画、转场)
- 所有可点击元素都使用
Button;添加无障碍分组和标签 - 使用
#available检查特定版本的 API,并提供回退方案
记录新的 Instruments 跟踪
当用户要求“记录跟踪”“分析应用性能”“捕获会话”等时触发。完整参考:references/trace-recording.md。
- 确认目标——连接到正在运行的应用、启动应用,还是记录所有进程?如果用户没有说明,请询问。必要时列出已连接的设备:
python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices - 根据目标类型选择模板——
SwiftUI模板会在任何真实设备上填充 SwiftUI 通道:实体 iOS/iPadOS 设备或主机 Mac。唯一的例外是 iOS Simulator,其 SwiftUI 通道会为空——此时切换到--template "Time Profiler"(仍会提供 Time Profiler + Hangs + Animation Hitches)。始终检查--list-devices:simulators类型 →Time Profiler;devices类型(真实设备和主机 Mac)→ 默认使用SwiftUI。完整决策表见references/trace-recording.md。 - 开始记录。对于由 Agent 驱动、且用户表示“我完成后会告诉你”的会话,在后台启动并使用停止文件:
对于交互式会话,只需告知用户完成后按 Ctrl+C。python3 "${SKILL_DIR}/scripts/record_trace.py" \ --device "<name|udid>" --attach "<AppName>" \ --stop-file /tmp/stop-trace --output ~/Desktop/session.trace - 发出停止信号——当用户表示已完成对应用的操作时,执行
touch /tmp/stop-trace。脚本会向 xctrace 发送 SIGINT 并等待最多 60 秒完成最终处理。 - 分析生成的跟踪文件(进入下方的“基于跟踪的改进”工作流)。
基于跟踪的改进(提供了 Instruments .trace 文件)
当用户的请求提到 .trace 文件时触发。目标 SwiftUI 源文件为可选项——如果提供了文件,请引用具体行;如果没有,请根据跟踪文件中已显示的视图名称和符号,建议检查位置。
完整参考:references/trace-analysis.md。组合模式概要:
- 确定分析范围。 问问自己:用户想分析整个跟踪文件,还是其中一部分?
- “聚焦于 X / X 之后 / X 和 Y 之间 / 在 X 期间” → 先确定时间窗口(见第 2 步)。
- 没有范围提示 → 分析整个跟踪文件。
- 确定时间窗口(仅在用户指定范围时)。 解析器提供两种发现模式:
两种模式都接受# Find a log that marks the start/end of the region of interest: python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \ --list-logs --log-message-contains "loaded feed" --log-limit 5 # Or list os_signpost intervals (paired begin/end), filterable by name: python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \ --list-signposts --signpost-name-contains "ImageDecode"--window START_MS:END_MS来限定发现范围。选择与用户描述相符的time_ms(用于日志)或start_ms/end_ms(用于标志点)。构造时间窗口,例如--window 10400:11700。 - 运行主要分析(可带
--window,也可不带):python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \ --json-only --top 10 [--window START_MS:END_MS] - 参照
references/trace-analysis.md解读——关键诊断指标:- 每个相关项中的
main_running_coverage_pct(<25% = 受阻;≥75% = CPU 密集型)。 swiftui-causes.top_sources揭示更新持续发生的原因——边数较多的来源(例如UserDefaultObserver.send())或范围较广的EnvironmentWriter条目,说明存在结构性失效问题。修复其中一个问题通常就能减少许多下游热点视图。
- 每个相关项中的
- 当某个视图显示为开销较高时,询问是谁导致它失效。 使用
--fanin-for "<view name>"获取驱动更新的来源节点排名列表。 - 可选:结合源代码确认。 如果用户指出了某个文件,请阅读该文件,并将视图名称/用户代码符号与其中的标识符匹配。如果没有,请根据 SwiftUI 报告的视图名称,建议打开哪些文件。
- 给出优先级排序的计划。 引用证据(覆盖率 %、热点符号、重叠视图、日志时间戳、原因图中的边),并将每条建议指向 Topic Router 参考资料。
- 仅在用户要求修改时编辑代码。
主题路由
请针对当前任务涉及的每个主题,查阅相应的参考文件:
| 主题 | 参考文件 |
|---|---|
| 状态管理 | references/state-management.md |
环境和 @Entry | references/environment-patterns.md |
| 视图组合 | references/view-structure.md |
| 视图修饰符和身份 | references/modifier-patterns.md |
| 性能 | references/performance-patterns.md |
| 列表和 ForEach | references/list-patterns.md |
| 可调整大小的布局、安全区域、双列重排、折叠屏网格、排列方式和预留区域 | references/layout-best-practices.md |
| iPhone Duo、折叠屏或大屏显示设备(先阅读以选择适用技术) | references/iphone-duo.md |
工作表、导航、大屏上的 NavigationSplitView,以及标签栏/侧边栏(sidebarAdaptable) | references/sheet-navigation-patterns.md |
| ScrollView、滚动位置和滚动几何信息 | references/scroll-patterns.md |
| 焦点管理 | references/focus-patterns.md |
| 动画(基础) | references/animation-basics.md |
| 动画(转场) | references/animation-transitions.md |
| 动画(高级) | references/animation-advanced.md |
| 无障碍功能 | references/accessibility-patterns.md |
| Swift Charts | references/charts.md |
| 图表无障碍功能 | references/charts-accessibility.md |
| 图像优化和显示缩放比例 | references/image-optimization.md |
| 工具栏 | references/toolbar-patterns.md |
| 基于文稿的应用 | references/document-apps.md |
| WebKit | references/webkit-integration.md |
| 富文本编辑 | references/styled-text-editing.md |
| Liquid Glass(iOS 26+) | references/liquid-glass.md |
| macOS 场景 | references/macos-scenes.md |
| macOS 窗口样式 | references/macos-window-styling.md |
| macOS 视图 | references/macos-views.md |
| 文本模式 | references/text-patterns.md |
| 本地化 | references/localization.md |
| 已弃用 API 查询 | references/latest-apis.md |
| 处理软弃用 API | references/soft-deprecation.md |
| 预览 | references/previews.md |
| Instruments 跟踪分析 | references/trace-analysis.md |
| Instruments 跟踪录制 | references/trace-recording.md |
正确性检查清单
以下均为硬性规则,违反即为缺陷:
-
@State属性必须为private - 仅当子视图会修改父视图状态时才使用
@Binding - 不得将会变化的父视图所有输入存储为
@State/@StateObject;有意设定的状态初始值必须注明仅用于一次性初始化 - 视图自身拥有的对象使用
@StateObject;注入的对象使用@ObservedObject - iOS 17+:
@Observable搭配@State;注入的可观察对象需要绑定时使用@Bindable -
ForEach使用稳定的标识(绝不使用.indices/\.offset;标识的生命周期必须长于视图,且不得由可变内容派生) - 每个
ForEach元素包含固定数量的视图;List行必须是单一视图 - 自定义
@Environment/@FocusedValue键中不得存储闭包 - 自定义
@Entry默认值必须稳定(不得使用Model()/Date()/UUID()表达式) - SwiftUI 显示缩放比例必须来自
@Environment(\.displayScale),而非全局屏幕状态 - 安全区域内容不得重复应用
GeometryProxy.safeAreaInsets -
.animation(_:value:)必须始终包含value参数 -
@FocusState属性必须为private - 在
.focusable()视图的点击手势处理程序中,不得冗余地写入@FocusState - 特定版本的 API 必须用
#available做条件判断,并提供合理的回退方案 - 使用图表类型的文件中必须包含
import Charts - 预览必须使用自包含的模拟数据,不得依赖在线服务或网络
评论
支持 Markdown