Communityコーディング&開発github.com

SwiftUIエキスパートスキル

iOS/macOS向けSwiftUIコードの作成、レビュー、リファクタリング時に使用します。状態管理、@Observableデータフロー、ビュー構成、レイアウト、セーフエリア、パフォーマンス、リスト、環境設定、ローカライゼーション、アニメーション、Liquid Glass、API移行などをカバーします。また、iPhone Duo、折りたたみディスプレイ、大画面レイアウト、ヒンジエフェクト、@State初期化、@ContentBuilderの曖昧さ、reorderableドラッグ&ドロップ、カスタムAsyncImage、リスト外でのスワイプアクション、ToolbarOverflowMenu、AnimatableValues、Document API、Instruments .traceのキャプチャ/分析も扱います。

SwiftUIエキスパートスキル とは?

このスキルは、SwiftUIアプリケーション開発におけるあらゆる側面をサポートする専門知識を提供します。iOS/macOS向けのSwiftUIコードの記述、レビュー、リファクタリング、そして新しい機能の実装に役立ちます。状態管理、@Obserableデータフロー、ビュー構成、パフォーマンス最適化、アニメーション、アクセシビリティ、レイアウト(サイドバー、スプリットビュー、二段組み、折りたたみグリッドなど)、Local Liquid Glass(iOS 26+)、API移行など、幅広いトピックをカバーしています。特に、Instrumentsのトレース記録と分析を円滑に行うためのスクリプトが組み込まれており、パフォーマンスのボトルネックを特定し、改善するための具体的な手順を提供します。このスキルは、Claude CodeなどのAIエージェントで使用することを想定して設計されており、各トピックに関する詳細なリファレンスファイルを参照しながら、正しく効率的な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に質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

SwiftUIエキスパートスキル は何をしますか?

運用ルール

  • 各View型は無効化境界(invalidation boundary)として扱い、ビューが読み取るデータのみを渡し、頻繁に変更される依存関係は影響が最も小さいサブツリーの近くに配置する
  • APIの使用、レビュー、移行時はreferences/latest-apis.mdを検索し、タスクに関連するAPIのみを参照する
  • ハード非推奨(hard-deprecated)のAPIは最新の同等品に置き換える。機能開発中はソフト非推奨(soft-deprecated)の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機能を実装する

  • 最初にデータフローを設計する:所有状態と注入状態を特定する
  • 最適な差分計算のためにビューを構造化する(早期にサブビューを抽出する)
  • 正しいアニメーションパターンを適用する(暗黙的 vs 明示的、トランジション)
  • すべてのタップ可能要素に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。

ハング(Hangs): xctrace helpがtriageをリストする場合(Xcode 27.2+)、xctrace triage <trace> --style hangsから開始し、次にxctrace showで詳細を掘り下げます。バンドルされたパーサーは、ヒッチ、SwiftUI更新、原因グラフ、ログまたはsignpostウィンドウに対して引き続きツールとして使用します。

パーサーの構成パターンの概要:

  1. 分析範囲を設定する。 自問する:ユーザーはトレース全体を望んでいるのか、それとも一部か?
    • 「Xに焦点を当てる / Xの後 / XとYの間 / Xの間」 → 最初にウィンドウを解決する(ステップ2参照)。
    • 範囲指定の手掛かりがない → トレース全体を分析する。
  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
Listと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
チャートのアクセシビリティ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
ソフト非推奨APIの取り扱いreferences/soft-deprecation.md
プレビューreferences/previews.md
Instrumentsトレース分析references/trace-analysis.md
Instrumentsトレース記録references/trace-recording.md

正確性チェックリスト

以下は厳格なルールです — 違反は常にバグです:

  • @Stateプロパティはprivateである
  • @Bindingは、子が親の状態を変更する場合にのみ使用する
  • 親が所有する変更可能な入力は@State/@StateObjectとして保存しない;意図的な初期状態の種は、1回限りとして文書化する
  • ビューが所有するオブジェクトには@StateObjectを、注入されたオブジェクトには@ObservedObjectを使用する
  • iOS 17+:@Stateは@Observableと共に;バインディングが必要な注入された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が存在する
  • プレビューは自己完結型のモックデータを使用する;ライブサービスやネットワークに依存しない

関連スキル