mcpField
S
swiftui-expert-skill

swiftui-expert-skill

github.com/sickn33開発48.8k289 回インストール今日更新
リポジトリ

swiftui-expert-skill について

コーディングエージェント向けの SwiftUI スキルです。実装、レビュー、リファクタリング、Instruments のトレース分析を、トピック別の資料とチェック項目で支援します。

主な機能

  1. 01SwiftUI の実装とレビュー
  2. 02状態管理とビュー構成の指針
  3. 03パフォーマンスとアクセシビリティの確認
  4. 04Instruments のトレース記録と分析

活用シーン

  1. 01SwiftUI コードの非推奨 API の確認
  2. 02バージョン別フォールバックを備えたビューの作成
  3. 03.trace ファイルを使った性能調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill swiftui-expert-skill

インストール後、Claude Code で/swiftui-expert-skillを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
accessibility-patterns.md
animation-basics.md
animation-transitions.md
focus-patterns.md
animation-advanced.md
charts.md
charts-accessibility.md
image-optimization.md
latest-apis.md
layout-best-practices.md
liquid-glass.md
macos-scenes.md
localization.md
performance-patterns.md
previews.md
macos-window-styling.md
macos-views.md
sheet-navigation-patterns.md
scroll-patterns.md
list-patterns.md
soft-deprecation.md
state-management.md
trace-recording.md
trace-analysis.md
view-structure.md
text-patterns.md
scripts/
analyze_trace.py
scripts/instruments_parser/
__init__.py
correlate.py
events.py

詳細

SwiftUI Expert Skill

使用するタイミング

iOS または macOS 向けの SwiftUI コードを作成、レビュー、リファクタリングするときに使用します。状態管理と @Observable データフロー、ビューの合成と無効化/パフォーマンス、リストと ForEach の identity、environment の使用、ローカライズ、アニメーション、Liquid Glass の採用、移行などが含まれます。

運用ルール

  • 非推奨 API を避けるため、すべてのタスクの開始時に references/latest-apis.md を参照する
  • ブリッジが必要な場合を除き、UIKit/AppKit のブリッジよりもネイティブの SwiftUI API を優先する
  • 正確性とパフォーマンスに焦点を当てる。特定のアーキテクチャ(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 機能を実装する
  • まずデータフローを設計する:所有される状態と注入される状態を特定する
  • 最適な差分検出のためにビューを構造化する(早い段階でサブビューを抽出する)
  • 正しいアニメーションパターンを適用する(暗黙的と明示的、トランジション)
  • タップ可能なすべての要素に Button を使用する。アクセシビリティのグループ化とラベルを追加する
  • バージョン固有の API を #available でゲートし、フォールバックを提供する
新しい Instruments トレースを記録する

ユーザーが「トレースを記録する」「アプリをプロファイリングする」「セッションをキャプチャする」などを求めたときにトリガーします。完全なリファレンス:references/trace-recording.md。

  1. ターゲットを確認する — 実行中のアプリにアタッチするか、アプリを起動するか、すべてのプロセスを記録するか?ユーザーが指定していない場合は尋ねてください。必要に応じて接続されているデバイスを一覧表示します:
    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-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 を実行します。スクリプトは xctrace にクリーンに SIGINT を送り、最大 60 秒間ファイナライズを待ちます。
  5. 結果のトレースを分析する(以下の「トレース駆動の改善」ワークフローに進みます)。
トレース駆動の改善(Instruments の .trace を提供)

ユーザーのリクエストが .trace ファイルを参照したときは常にトリガーします。対象となる SwiftUI ソースファイルは任意です。指定された場合は具体的な行を引用し、指定されていない場合はトレースがすでに明らかにしているビュー名とシンボルに基づいて、どこを確認すべきかを提案します。

完全なリファレンス: references/trace-analysis.md。構成パターンの概要:

  1. 分析の範囲を決める。 自問してください: ユーザーはトレース全体を求めているのか、それとも一部を求めているのか?
    • 「X に注目」「X の後」「X と Y の間」「X の間」→ まずウィンドウに解決する(ステップ 2 を参照)。
    • 範囲指定の手がかりがない → トレース全体を分析する。
  2. ウィンドウを解決する(ユーザーが範囲を指定した場合のみ)。 パーサーは 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(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 を使って解釈する — 主要な診断項目:
    • 各 correlation 内の main_running_coverage_pct(<25% = ブロックされている; ≥75% = CPU バウンド)。
    • swiftui-causes.top_sources は、なぜ更新が繰り返し発生し続けるのかを明らかにします — UserDefaultObserver.send() のようなエッジ数の多いソースや、幅の広い EnvironmentWriter のエントリは構造的な無効化バグです。1 つを修正すると、多くの下流のホットビューがまとめて解消されることがよくあります。
  5. 特定のビューが高コストとして現れたら、誰がそれを無効化しているのかを問う。 --fanin-for "<view name>" を使うと、更新を引き起こしているソースノードのランキングリストを取得できます。
  6. 任意でソースに基づいて根拠づける。 ユーザーがファイルを指定した場合は、それを読み、ビュー名やユーザーコードのシンボルをその中の識別子と照合します。指定していない場合は、SwiftUI が報告したビュー名に基づいて、どのファイルを開くべきかを提案します。
  7. 優先順位付けされた計画を返す。 根拠(カバレッジ率、ホットシンボル、重複するビュー、ログのタイムスタンプ、原因グラフのエッジ)を引用し、各推奨事項を Topic Router のリファレンスにルーティングします。
  8. ユーザーが編集を求めた場合にのみコードを編集します。
Topic Router

現在のタスクに関連する各トピックについて、リファレンスファイルを参照してください:

トピックリファレンス
状態管理references/state-management.md
ビューの構成references/view-structure.md
パフォーマンスreferences/performance-patterns.md
リストと ForEachreferences/list-patterns.md
レイアウトreferences/layout-best-practices.md
シートとナビゲーションreferences/sheet-navigation-patterns.md
ScrollViewreferences/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
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 を使用する; バインディングが必要な注入された Observable には @Bindable を使用する
  • ForEach は安定した ID を使用する (.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 の identity、Table (iOS 16+)、インラインフィルタリングの落とし穴
  • references/layout-best-practices.md -- レイアウトパターン、GeometryReader の代替
  • references/accessibility-patterns.md -- VoiceOver、Dynamic Type、グループ化、traits
  • references/animation-basics.md -- 暗黙的/明示的アニメーション、タイミング、パフォーマンス
  • references/animation-transitions.md -- ビューのトランジション、matchedGeometryEffect、Animatable
  • 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 -- シート、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+)、プレビューの traits、自己完結型プレビュー用のモックデータパターン
  • references/text-patterns.md -- Text イニシャライザの選択、verbatim とローカライズの比較
  • references/localization.md -- String Catalogs、パッケージ用の #bundle、LocalizedStringResource、ロケール対応のフォーマット、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 で新しいトレースを記録します。実行中のアプリにアタッチする、新規に起動する、手動で停止したセッションをキャプチャする、といったことが可能です。エージェント駆動のフロー向けの stop-file もサポートします

制限事項

  • このスキルは、タスクがその上流ソースとローカルプロジェクトのコンテキストに明確に一致する場合にのみ使用してください。
  • 変更を適用する前に、コマンド、生成されたコード、依存関係、認証情報、外部サービスの動作を確認してください。
  • 破壊的または高コストな操作については、例を環境固有のテスト、セキュリティレビュー、ユーザーの承認の代わりとして扱わないでください。

コメント