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。
- 確認目標 — 附加到正在執行的應用程式、啟動應用程式,或記錄所有程序?如果使用者未說明,請詢問。在有用時列出已連接的裝置:
python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices - 根據目標種類選擇模板 —
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。 - 開始記錄。對於由代理驅動的工作階段,當使用者說「我完成時會告訴你」時,在背景啟動並使用停止檔案:
對於互動式工作階段,只需告訴使用者在完成時按 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。腳本會乾淨地 SIGINT 掉 xctrace 並等待最多 60 秒以完成最終處理。 - 分析 產生的軌跡(進入下面的「軌跡驅動改進」工作流程)。
軌跡驅動改進(提供了 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 視窗的工具。
解析器組成模式的摘要:
- 界定分析範圍。 捫心自問:使用者想要整個軌跡,還是某個片段?
- "專注於 X / 在 X 之後 / 在 X 和 Y 之間 / 在 X 期間" → 首先解析出一個視窗(參見步驟 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這樣的視窗參數。 - 執行主要分析(可選
--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 報告的視圖名稱建議應開啟哪些檔案。
- 返回一個排定優先順序的計劃。 引用證據(覆蓋率百分比、熱門符號、重疊視圖、日誌時間戳、原因圖邊緣),並將每個建議路由到主題路由參考。
- 僅在使用者要求編輯時才編輯程式碼。
主題路由
對於與當前任務相關的每個主題,請查閱其參考檔案:
| 主題 | 參考檔案 |
|---|---|
| 狀態管理 | references/state-management.md |
環境和 @Entry,包括「在 '@Entry var' 中儲存閉包/類別類型」的警告 | 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 |
| Charts 無障礙 | 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+:使用
@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 - 預覽使用自包含的模擬資料;不依賴即時服務或網路