swiftui-expert-skill

swiftui-expert-skill

熱門

用於撰寫、審查或重構 iOS 或 macOS 的 SwiftUI 程式碼,包含狀態管理與 `@Observable` 資料流、檢視組合與失效/效能、列表與 `ForEach` 識別、環境使用、本地化、動畫、Liquid Glass 採用、遷移軟棄用 API,或使用 Instruments `.trace` 擷取/分析卡頓、掉幀、CPU 熱點或過多檢視更新。

3082星標
146分支
更新於 2026/6/16
SKILL.md
readonlyread-only
name
swiftui-expert-skill
description

用於撰寫、審查或重構 iOS 或 macOS 的 SwiftUI 程式碼,包含狀態管理與 `@Observable` 資料流、檢視組合與失效/效能、列表與 `ForEach` 識別、環境使用、本地化、動畫、Liquid Glass 採用、遷移軟棄用 API,或使用 Instruments `.trace` 擷取/分析卡頓、掉幀、CPU 熱點或過多檢視更新。

SwiftUI Expert Skill

操作規則

  • 每次任務開始時先查閱 references/latest-apis.md,避免使用已棄用的 API
  • 除非必要,否則優先使用原生 SwiftUI API 而非 UIKit/AppKit 橋接
  • 專注於正確性與效能;不強制特定架構(MVVM、VIPER 等)
  • 鼓勵將商業邏輯與檢視分離以提升可測試性,但不強制特定做法
  • 遵循 Apple 的 Human Interface Guidelines 與 API 設計模式
  • 僅在使用者明確要求時才採用 Liquid Glass(參見 references/liquid-glass.md
  • 將效能最佳化視為建議而非必要條件
  • 對版本特定 API 使用 #available 搭配合理的降級方案

任務流程

審查現有 SwiftUI 程式碼

  • 閱讀待審查的程式碼,判斷哪些主題適用
  • 標記已棄用的 API(對照 references/latest-apis.md
  • 針對每個相關主題執行下方的主題路由器
  • 驗證 iOS 26+ 功能的 #available 防護與降級路徑

改善現有 SwiftUI 程式碼

  • 根據主題路由器的主題審查目前實作
  • 將棄用 API 替換為 references/latest-apis.md 中的現代等效 API
  • 重構熱點路徑以減少不必要的狀態更新
  • 將複雜的檢視主體拆分為獨立的子檢視
  • 遇到 UIImage(data:) 時建議圖片降採樣(選擇性最佳化,參見 references/image-optimization.md

實作新的 SwiftUI 功能

  • 先設計資料流:區分擁有狀態與注入狀態
  • 為最佳差異化建構檢視(及早提取子檢視)
  • 套用正確的動畫模式(隱式 vs 顯式、轉場)
  • 所有可點擊元素使用 Button;加入無障礙分組與標籤
  • 使用 #available 防護版本特定 API 並提供降級方案

錄製新的 Instruments trace

當使用者要求「錄製 trace」、「分析 App」、「擷取 session」等時觸發。完整參考:references/trace-recording.md

  1. 確認目標 — 附加到執行中的 App、啟動 App、或錄製所有程序?若使用者未說明,請詢問。必要時列出已連接裝置:
    python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices
    
  2. 根據目標類型選擇模板SwiftUI 模板會在真實裝置(實體 iOS/iPadOS 裝置或主機 Mac)上填入 SwiftUI 跑道。唯一的例外是 iOS 模擬器,SwiftUI 跑道會是空的 — 此時改用 --template "Time Profiler"(仍提供 Time Profiler + Hangs + Animation Hitches)。務必檢查 --list-devicessimulators 類型 → Time Profilerdevices 類型(真實裝置與主機 Mac)→ 預設 SwiftUI。完整決策表在 references/trace-recording.md
  3. 開始錄製。對於代理驅動的 session(使用者說「我完成時告訴你」),在背景啟動並使用停止檔案:
    python3 "${SKILL_DIR}/scripts/record_trace.py" \
        --device "<name|udid>" --attach "<AppName>" \
        --stop-file /tmp/stop-trace --output ~/Desktop/session.trace
    
    對於互動式 session,直接告知使用者完成時按 Ctrl+C。
  4. 發出停止訊號 — 當使用者表示已操作完 App 時,執行 touch /tmp/stop-trace。腳本會乾淨地對 xctrace 發送 SIGINT 並等待最多 60 秒完成。
  5. 分析 產生的 trace(進入下方的「Trace 驅動改善」流程)。

Trace 驅動改善(提供 Instruments .trace

每當使用者的請求提及 .trace 檔案時觸發。目標 SwiftUI 原始檔是選擇性的 — 若有提供,引用特定行數;若無,根據 trace 已揭露的檢視名稱與符號建議應查看的位置。

完整參考:references/trace-analysis.md。組合模式摘要:

  1. 界定分析範圍。 問自己:使用者想要整個 trace,還是某個片段?
    • 「聚焦在 X / 在 X 之後 / 在 X 與 Y 之間 / 在 X 期間」 → 先解析出時間區間(見步驟 2)。
    • 無範圍提示 → 分析整個 trace。
  2. 解析時間區間(僅在使用者指定範圍時)。 解析器提供兩種探索模式:
    # 尋找標記感興趣區域開始/結束的日誌:
    python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
        --list-logs --log-message-contains "loaded feed" --log-limit 5
    # 或列出 os_signpost 區間(成對的 begin/end),可按名稱篩選:
    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(signpost)。建構類似 --window 10400:11700 的區間。
  3. 執行主要分析(可加或不加 --window):
    python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
        --json-only --top 10 [--window START_MS:END_MS]
    
  4. 搭配 references/trace-analysis.md 解讀 — 關鍵診斷:
    • 每個關聯中的 main_running_coverage_pct(<25% = 被阻塞;≥75% = CPU 密集)。
    • swiftui-causes.top_sources 揭示更新持續發生的原因 — 高邊緣計數的來源如 UserDefaultObserver.send() 或寬廣的 EnvironmentWriter 條目屬於結構性失效錯誤。修正一個通常能消除許多下游熱點檢視。
  5. 當特定檢視顯示為昂貴時,詢問是誰在使其失效。 使用 --fanin-for "<view name>" 取得驅動更新的來源節點排名列表。
  6. 選擇性對應到原始碼。 若使用者指定了檔案,讀取該檔案並將檢視名稱/使用者程式碼符號與其中的識別符匹配。若無,根據 SwiftUI 回報的檢視名稱建議應開啟哪些檔案。
  7. 回傳優先順序計畫。 引用證據(覆蓋率百分比、熱點符號、重疊檢視、日誌時間戳、原因圖邊緣),並將每個建議導向主題路由器參考。
  8. 僅在使用者要求編輯時才編輯程式碼。

主題路由器

針對目前任務相關的每個主題,查閱對應的參考檔案:

主題 參考
狀態管理 references/state-management.md
檢視組合 references/view-structure.md
效能 references/performance-patterns.md
列表與 ForEach references/list-patterns.md
佈局 references/layout-best-practices.md
Sheet 與導航 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
Charts 無障礙 references/charts-accessibility.md
圖片最佳化 references/image-optimization.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 trace 分析 references/trace-analysis.md
Instruments trace 錄製 references/trace-recording.md

正確性檢查清單

以下是硬性規則 — 違反即為錯誤:

  • [ ] @State 屬性為 private
  • [ ] @Binding 僅用於子檢視修改父檢視狀態
  • [ ] 傳入的值絕不宣告為 @State@StateObject(它們會忽略更新)
  • [ ] @StateObject 用於檢視擁有的物件;@ObservedObject 用於注入的物件
  • [ ] iOS 17+:@State 搭配 @Observable@Bindable 用於需要綁定的注入可觀察物件
  • [ ] ForEach 使用穩定的識別(絕不使用 .indices/\.offset;id 的生命週期超過檢視,且不從可變內容衍生)
  • [ ] 每個 ForEach 元素的檢視數量固定;List 行數為一元
  • [ ] 自訂 @Environment/@FocusedValue 鍵中不儲存閉包
  • [ ] 自訂 @Entry 預設值為穩定的(無 Model()/Date()/UUID() 表達式)
  • [ ] .animation(_:value:) 總是包含 value 參數
  • [ ] @FocusState 屬性為 private
  • [ ] 在 .focusable() 檢視的點擊手勢處理器中無多餘的 @FocusState 寫入
  • [ ] iOS 26+ API 使用 #available 防護並提供降級方案
  • [ ] 使用圖表類型的檔案中包含 import Charts
  • [ ] 預覽使用自包含的模擬資料;不依賴即時服務或網路

參考資料

  • references/latest-apis.md每次任務先讀取。 從棄用到現代的 API 轉換(iOS 15+ 到 iOS 26+)
  • references/state-management.md — 屬性包裝器、資料流、@Observable 遷移
  • references/view-structure.md — 檢視提取、容器模式、@ViewBuilder
  • references/performance-patterns.md — 熱點路徑最佳化、更新控制、_logChanges()
  • references/list-patterns.md — ForEach 識別、Table(iOS 16+)、內聯篩選陷阱
  • references/layout-best-practices.md — 佈局模式、GeometryReader 替代方案
  • references/accessibility-patterns.md — VoiceOver、Dynamic Type、分組、特性
  • references/animation-basics.md — 隱式/顯式動畫、時序、效能
  • references/animation-transitions.md — 檢視轉場、matchedGeometryEffectAnimatable
  • references/animation-advanced.md — 階段/關鍵幀動畫(iOS 17+)、@Animatable 巨集(iOS 26+)
  • references/charts.md — Swift Charts 標記、軸、選取、樣式、Chart3D(iOS 26+)
  • references/charts-accessibility.md — Charts VoiceOver、Audio Graph、降級策略
  • references/sheet-navigation-patterns.md — Sheets、NavigationSplitView、Inspector
  • references/scroll-patterns.md — ScrollViewReader、程式化滾動
  • references/focus-patterns.md — 焦點狀態、可聚焦檢視、聚焦值、預設焦點、常見陷阱
  • references/image-optimization.md — AsyncImage、降採樣、快取
  • references/liquid-glass.md — iOS 26+ Liquid Glass 效果與降級模式
  • references/macos-scenes.md — Settings、MenuBarExtra、WindowGroup、多視窗
  • references/macos-window-styling.md — 工具列樣式、視窗大小、Commands
  • references/macos-views.md — HSplitView、Table、PasteButton、AppKit 互通
  • references/previews.md#Preview 巨集、@Previewable(iOS 18+)、預覽特性、自包含預覽的模擬資料模式
  • references/text-patterns.md — Text 初始化器選擇、逐字 vs 本地化
  • references/localization.md — String Catalogs、套件的 #bundleLocalizedStringResource、語言感知格式化、RTL 佈局、翻譯者註解
  • references/soft-deprecation.md — 如何處理軟棄用 API(何時遷移、範圍規則、不相關編輯時不遷移)
  • references/trace-analysis.md — 透過 scripts/analyze_trace.py 解析 Instruments .trace 檔案;解讀主執行緒覆蓋率、高嚴重性 SwiftUI 更新、掉幀敘述,並將發現對應回原始檔
  • references/trace-recording.md — 透過 scripts/record_trace.py 錄製新的 trace:附加到執行中的 App、全新啟動、或擷取手動停止的 session;支援代理驅動流程的停止檔案