Community程式設計與開發github.com

SwiftUI 專家技能

用於撰寫、審查或重構 iOS 或 macOS 的 SwiftUI 程式碼,包括狀態與 @Observable 資料流、視圖組合、可調整佈局、安全區域、顯示比例、效能、列表、環境、本地化、動畫、Liquid Glass 以及 API 遷移。

SwiftUI 專家技能 是什麼?

此 SwiftUI 專家技能旨在協助開發者處理與 SwiftUI 相關的各種任務,包括撰寫、審查、重構程式碼,以及使用 Instruments 進行效能分析。它涵蓋了從基本的狀態管理(如 `@Observable` 資料流)到進階的佈局技術(如 `NavigationSplitView`、可折疊螢幕適配、`ArrangementView`),再到動畫、本地化和 API 遷移等廣泛主題。此技能特別強調正確性與效能,並內建一套規則,例如要求 `@State` 屬性必須為私有,以及鼓勵將業務邏輯從視圖中分離以提升可測試性。它支援 Claude Code、Cursor 和 Codex 等 AI 代理平台,並透過多個參考文件提供深入的主題指引,例如 UIKit 取代方案、效能模式、列表處理以及 Liquid Glass(iOS 26+)等新功能。此外,它也整合了 Instruments 的記錄與分析工作流程,幫助開發者診斷懸滯、動畫卡頓和 SwiftUI 更新衝突等問題,並提供可操作的改善建議。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/erumkatzwan/agentic-product-starter/tree/HEAD/apps/ios/.agents/skills/swiftui-expert

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

SwiftUI 專家技能 是做什麼的?

操作規則

  • 將每個 View 類型視為一個失效邊界:只提供它讀取的資料,並將頻繁變化的依賴項盡量保持在最小的受影響子樹中
  • 在撰寫、審查或遷移 API 使用時,搜尋 references/latest-apis.md;只查詢與任務相關的 API
  • 用現代等效 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 守衛和特定版本功能的備用路徑
  • 對於廣泛的程式碼庫審查,先識別較小的重點區域並逐一呈現;如果使用者要求全程式碼庫審查,則將其分解為待辦事項清單

改進現有的 SwiftUI 程式碼

  • 根據主題路由的主題審核當前實作
  • 使用 references/latest-apis.md 中的現代等效 API 取代硬性棄用的 API;標記軟性棄用的 API,並在功能開發期間不改寫它們
  • 重構熱點路徑以減少不必要的狀態更新
  • 將複雜的視圖主體提取為單獨的子視圖
  • 當遇到 UIImage(data:) 時,建議進行圖片降採樣(可選最佳化,參閱 references/image-optimization.md)

實作新的 SwiftUI 功能

  • 首先設計資料流:識別擁有的狀態與注入的狀態
  • 為最佳差異化建構視圖(盡早提取子視圖)
  • 應用正確的動畫模式(隱式 vs 顯式、轉場)
  • 為所有可點擊元素使用 Button;添加無障礙分組和標籤
  • 使用 #available 守衛特定版本的 API,並提供備用方案

記錄新的 Instruments 軌跡

當使用者要求「記錄軌跡」、「對應用程式進行效能分析」、「擷取工作階段」等時觸發。完整參考:references/trace-recording.md。

  1. 確認目標 — 附加到正在執行的應用程式、啟動應用程式,或記錄所有程序?如果使用者未說明,請詢問。在有用時列出已連接的裝置:
    python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices
    
  2. 根據目標種類選擇模板 — SwiftUI 模板會在真實裝置上填入 SwiftUI 通道:實體 iOS/iPadOS 裝置或主機 Mac。唯一的例外是 iOS 模擬器,在該處 SwiftUI 通道會返回空的 — 在這種情況下切換為 --template "Time Profiler"(提供 Time Profiler + Hangs,但沒有 Animation Hitches)。始終檢查 --list-devices:simulators 種類 → Time Profiler;devices 種類(真實裝置和主機 Mac)→ 預設 SwiftUI。完整決策表請參閱 references/trace-recording.md。
  3. 開始記錄。對於由代理驅動的工作階段,當使用者說「我完成時會告訴你」時,在背景啟動並使用停止檔案:
    python3 "${SKILL_DIR}/scripts/record_trace.py" \
        --device "<name|udid>" --attach "<AppName>" \
        --stop-file /tmp/stop-trace --output ~/Desktop/session.trace
    
    對於互動式工作階段,只需告訴使用者在完成時按 Ctrl+C。
  4. 發出停止訊號 — 當使用者表示已完成操作應用程式時,touch /tmp/stop-trace。腳本會乾淨地 SIGINT 掉 xctrace 並等待最多 60 秒以完成最終處理。
  5. 分析 產生的軌跡(進入下面的「軌跡驅動改進」工作流程)。

軌跡驅動改進(提供了 Instruments .trace 檔案)

每當使用者的請求提及 .trace 檔案時觸發。目標 SwiftUI 原始碼檔案是可選的 — 如果給定,則引用特定行;如果沒有,則根據軌跡已揭示的視圖名稱和符號來建議應該查看的位置。

完整參考:references/trace-analysis.md。

懸滯(Hangs): 如果 xctrace help 列出了 triage(Xcode 27.2 有此功能),則從 xctrace triage <trace> --style hangs 開始,然後使用 xctrace show 深入鑽研。捆綁的解析器仍然是分析卡頓(hitches)、SwiftUI 更新、原因圖以及日誌或 signpost 視窗的工具。

解析器組成模式的摘要:

  1. 界定分析範圍。 捫心自問:使用者想要整個軌跡,還是某個片段?
    • "專注於 X / 在 X 之後 / 在 X 和 Y 之間 / 在 X 期間" → 首先解析出一個視窗(參見步驟 2)。
    • 沒有範圍提示 → 分析整個軌跡。
  2. 解析視窗(僅在使用者指定了範圍時)。 解析器提供兩種探索模式:
    # 找到標記感興趣區域起點/終點的日誌:
    python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
        --list-logs --log-message-contains "loaded feed" --log-limit 5
    # 或列出 os_signpost 區間(成對的開始/結束),可按名稱過濾:
    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
環境和 @Entry,包括「在 '@Entry var' 中儲存閉包/類別類型」的警告references/environment-patterns.md
視圖組合references/view-structure.md
視圖修飾符和身份references/modifier-patterns.md
效能references/performance-patterns.md
列表與 ForEachreferences/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 Chartsreferences/charts.md
Charts 無障礙references/charts-accessibility.md
圖片最佳化與顯示比例references/image-optimization.md
工具列references/toolbar-patterns.md
基於文件的應用程式references/document-apps.md
WebKitreferences/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
處理軟性棄用的 APIreferences/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+:使用 @State 搭配 @Observable;使用 @Bindable 處理需要綁定的注入可觀察物件
  • ForEach 使用穩定的身份(永遠不要使用 .indices/\.offset;id 的生命週期長於視圖,並且不能從可變內容派生)
  • 每個 ForEach 元素的視圖數量是恆定的;List 行是單一的
  • 閉包不儲存在自訂的 @Environment/@FocusedValue 鍵中
  • 自訂 @Entry 的預設值是穩定的(沒有 Model()/Date()/UUID() 表達式)
  • SwiftUI 顯示比例來自 @Environment(\.displayScale),而非全域的螢幕狀態
  • 安全區域內容不會重複應用 GeometryProxy.safeAreaInsets
  • .animation(_:value:) 始終包含 value 參數
  • @FocusState 屬性是 private
  • 在 .focusable() 視圖的點擊手勢處理程式中,沒有冗餘的 @FocusState 寫入
  • 特定版本的 API 使用 #available 進行守衛,並有合理的備用方案
  • 使用圖表類型的檔案中需有 import Charts
  • 預覽使用自包含的模擬資料;不依賴即時服務或網路

相關技能