AIエージェントでiOSアプリを開発する:実践者のためのガイド
# AIエージェントを活用してiOSアプリをより迅速に開発します。Claude Code、Codex CLI、Xcode 27のエージェント、MCP、CLAUDE.mdのパターン、フック、8つのアプリから得た知見を紹介します。
要約: 現在、iOS向けのコードを出荷できるエージェントランタイムは3つあります。Claude Code CLI と MCP、Codex CLI と MCP、そしてXcodeネイティブのIntelligenceエージェントです。これにはClaude Agent、Codex、さらにXcode 26.6以降ではGoogle Geminiまたは任意のAgent Client Protocol(ACP)エージェントが含まれます。17 2つのMCPサーバー(82個のツールを持つXcodeBuildMCPと、20個のツールを持つAppleの
xcrun mcpbridge)により、エージェントはビルド、テスト、シミュレータ、デバッグへ構造化された形でアクセスできます。このガイドでは、実際のCLAUDE.mdパターン、hook設定、機能することと壊れることの率直な評価を取り上げます。対象は合計293個のSwiftファイルからなる、8本の本番iOSアプリです。32 エージェントはSwiftUIビュー、SwiftDataモデル、リファクタリング、ビルドエラーの診断に優れています。一方で、.pbxprojの変更、コード署名、視覚的なデバッグは苦手です。「エージェントがSwiftを書く」と「エージェントがiOSアプリを出荷する」の隔たりを埋めるのは、プロンプトではなく設定です。WWDC 2026(6月8日)時点で、iOS 27はベータです。8月10日時点ではbeta 5(24A5408d)であり、エージェントに関連するフレームワーク(Foundation Modelsのtool-calling制御、App Intentsのバックグラウンド実行、新しいCore AIおよびEvaluationsフレームワーク)が追加されています。2026年6月より前に学習されたモデルはこれらを知らないため、エージェントのコンテキストで明示しておく価値があります。Xcode 26.6(2026-06-25、Swift 6.3)が現在の安定したツールチェーンです。Xcode 27 beta(Swift 6.4、iOS 27 SDKs)はiOS 27サイクルを追っています。1718
AIコーディングエージェントを使って、8本のiOSアプリを作ってきました。プロトタイプではありません。HealthKit連携、Metalシェーダー、SpriteKit物理演算、iCloud同期、Live Activities、Game Centerリーダーボード、そしてiOS、watchOS、tvOSにまたがるマルチプラットフォームターゲットを備えた、App Store公開済みのアプリです。これらのアプリのSwiftコードはすべて、エージェントが書いて私がレビューしたもの、または私が書いてエージェントがリファクタリングしたものです。私の見積もりでは、行レベルのコード作成の大部分をエージェントが担い、私はレビュー、スコープ設定、人間の判断が必要な部分(視覚的な磨き込み、署名、パフォーマンス調整、App Storeへの提出)を担当しました。
このガイドは、始めた当時にあればよかったと思うリファレンスです。使用するエージェントランタイムの選び方、構造化されたビルドアクセスのためのMCPサーバー設定、CLAUDE.mdに書く内容、エージェントによるXcodeプロジェクトの破壊を防ぐhook、そして重要な点として、エージェントが失敗し自分で操作を引き継ぐべき場面まで、フルスタックで扱います。
要点
AIエージェントを初めて使うiOS開発者向け:
- Claude Code CLI + XcodeBuildMCPから始めましょう。 最も成熟したランタイムであり、最も充実したMCPツールカバレッジを備えています。2つのコマンドをインストールして、プロジェクトにCLAUDE.mdを追加すれば、エラーをコピーして貼り付けなくても、エージェントがビルド、テスト、デバッグを行えます。
- エージェントに.pbxprojを変更させないでください。 これは最も重要なルールです。
.pbxprojと.xcodeproj/への書き込みをブロックするPreToolUse hookがあれば、復旧にかかる何時間もの作業を省けます。 - CLAUDE.mdはエージェント向けのオンボーディング文書です。 ここにかけた時間は、プロジェクトに触れるすべてのエージェントセッションで回収できます。
iOSをワークフローに加える、経験豊富なエージェントユーザー向け:
- MCPはiOSのビルドループを変えます。 MCP以前は、エージェントはSwiftを書けても、コンパイルできるか確認できませんでした。XcodeBuildMCPでは、エージェントがコードを書き、ビルドし、構造化されたエラーを読み、修正し、テストを実行します。すべて自律的に行えます。
- 3つのランタイムは異なるニーズに対応します。 深いエージェントセッションにはClaude Code CLI、ヘッドレスのバッチ作業にはCodex CLI、そしてXcode独自のエージェントです。Xcode独自のエージェントは、Xcode 27でインライン修正ツールの域を超え、プラグイン、MCPサーバー、シミュレータを操作する能力を獲得しました。22
- hookインフラはそのまま流用できます。 既存のPostToolUseフォーマッター、PreToolUseブロッカー、テストランナーhookは、パスをわずかに調整するだけでiOSプロジェクトでも同様に機能します。
AI支援iOS開発を評価するチームリード向け:
- エージェントの有効性は、プロジェクト規模ではなくプロジェクトドキュメントに比例します。 詳細なCLAUDE.mdを持つ63ファイルのアプリは、何もない14ファイルのアプリよりも優れたエージェント出力を生みます。
- .pbxprojの境界は譲れません。 エージェントはXcodeプロジェクトファイルを確実に編集できません。ワークフローには、Xcodeターゲットへの手動ファイル追加を組み込む必要があります。
- 率直なROI:十分に文書化されたプロジェクトでは、エージェントが実装の大部分を担います。 これは、エージェント支援による3時間の作業で出荷した15ファイルのTVアプリに表れています(下記ケーススタディ)。残る作業、つまり視覚的な磨き込み、署名、パフォーマンス調整、App Storeへの提出には、人間の判断が必要です。
目的別の案内
| 必要なこと | こちらへ |
|---|---|
| 初めてMCPを設定する | MCPセットアップ:完全設定ガイド — 両方のサーバーのインストール、検証、エージェント設定 |
| iOSプロジェクト用のCLAUDE.mdを書く | iOSプロジェクトのCLAUDE.mdパターン — 8アプリの実例 |
| 3つのエージェントランタイムを比較する | iOS向け3つのエージェントランタイム — Claude Code vs. Codex vs. Xcodeネイティブ |
| エージェントにできること・できないことを理解する | エージェントが得意なこととエージェントが苦手なこと |
| iOS開発向けhookを設定する | iOS開発向けhooks — 保存時フォーマット、.pbxproj保護、テストランナー |
| 詳細なリファレンス(このページ) | このまま読み進めてください — セットアップから高度なパターンまですべてを扱います |
このガイドの使い方
これは3,000行を超えるリファレンスです。経験レベルに合う場所から始めてください。
| 経験 | まずはこちら | 次に読むもの |
|---|---|---|
| iOS + エージェント初心者 | 前提条件 → MCPセットアップ → 最初のエージェントセッション | CLAUDE.mdパターン、うまくいくこと/いかないこと |
| iOS開発者、エージェント初心者 | 3つのランタイム → MCPセットアップ → CLAUDE.md | Hooks、アーキテクチャパターン |
| エージェントユーザー、iOS初心者 | アーキテクチャパターン → エージェントが苦手なこと → CLAUDE.md | フレームワーク別コンテキスト、高度なワークフロー |
| 両方に精通している方 | 高度なワークフロー → Hooks → マルチプラットフォームパターン | ランタイム比較、ポートフォリオ |
目次
- ポートフォリオ:8アプリ、293ファイル
- 前提条件
- iOS向け3つのエージェントランタイム
- MCPセットアップ:完全設定ガイド
- iOSプロジェクトのCLAUDE.mdパターン
- 最初のエージェントセッション
- iOSでエージェントが得意なこと
- iOSでエージェントが苦手なこと
- iOS開発向けhooks
- エージェントと相性のよいアーキテクチャパターン
- フレームワーク別コンテキスト
- マルチプラットフォームパターン
- 高度なワークフロー
- 実践的なケーススタディ
- エージェントを使うプロジェクトライフサイクル
- エージェント定義の設定
- エージェント支援iOS向けテストパターン
- iOSプロジェクトにおけるコンテキストウィンドウ管理
- トラブルシューティング
- iOSにおけるよくあるエージェントの失敗と防止策
- 率直な評価
- FAQ
- クイックリファレンスカード
- 参考文献
関連リソース
| トピック | リソース |
|---|---|
| Xcode向けMCPセットアップ(短いブログ記事) | 2つのMCPサーバーがClaude CodeをiOSビルドシステムに変えた |
| Claude Code CLI完全リファレンス | Claude Code CLI:完全ガイド |
| Codex CLIリファレンス | Codex CLI:完全ガイド |
| Hookシステムの詳細解説 | Anatomy of a Claw: 84 Hooks as an Orchestration Layer |
| エージェントアーキテクチャパターン | エージェントアーキテクチャガイド |
| Macデスクトップアプリ + Remote Control | Claude Code Mac Desktop + Remote Control:CLIユーザーガイド |
Apple Ecosystemシリーズ。 Apple Intelligence、MCP、Foundation Models、Vision、Core ML、iOS 26フレームワークスタックと統合するSwiftUIアプリに関する、21本の本番向け記事です。Water、Get Bananas、Return、そのほか941ポートフォリオのアプリから得た知見をまとめています。
シリーズハブ: Apple Ecosystemシリーズ
Agentic Apple(E4):
| トピック | リソース |
|---|---|
| Apple Intelligenceのインテントサーフェス | App Intents Are Apple’s New API to Your App |
| iOSアプリと並行するMCPサーバー | Two Agent Ecosystems, One Shopping List |
| どちらを使うべきか | App Intents vs MCP Tools: The Routing Question |
| オンデバイスLLMをランタイム機能として使うか、ツールとして使うか | Foundation Models + Agentic Workflow |
| Apple開発向けhooks | Hooks for Apple Development |
| プロセスをまたぐ状態 | Single Source of Truth: SwiftData + MCP + iCloud |
フレームワーク(E2/E3):
| トピック | リソース |
|---|---|
| Foundation ModelsのオンデバイスLLM | Foundation Models On-Device LLM |
| Visionフレームワーク(CVプリミティブ) | Vision Framework: What’s Built In |
| Core ML推論パターン | Core ML On-Device Inference |
| RealityKitの空間的メンタルモデル | RealityKit and the Spatial Mental Model |
| SwiftUIの内部構造 | What SwiftUI Is Made Of |
| Symbol Effectsのアニメーション語彙 | Symbol Effects: SwiftUI’s Built-In Animation Vocabulary |
| iOS 26以降のLiquid Glass | Liquid Glass in SwiftUI: Three Patterns |
出荷済みコード(E1):
| トピック | リソース |
|---|---|
| Live Activitiesの状態マシン | Live Activities State Machine |
| watchOSランタイム契約 | watchOS Runtime Contract |
| SwiftDataスキーマの規律 | SwiftData Schema Discipline |
| HealthKit + SwiftUIパターン | HealthKit + SwiftUI on iOS 26 |
| マルチプラットフォームSwiftUI | Five Apple Platforms, Three Shared Files |
| XcodeBuildMCP統合 | Two MCP Servers, One Xcode Project |
統合(E5):
| トピック | リソース |
|---|---|
| iOSアプリの3つのサーフェス | The Three Surfaces of an iOS App |
| プラットフォームターゲットの判断 | The Apple Platform Matrix |
| 私が書くことを断るテーマ | What I Refuse to Write About |
iOS 27 と WWDC 2026:エージェントが新たに構築できるもの
WWDC 2026(2026年6月8日)で iOS 27 のベータ版が公開されました。このガイドのエージェント開発ワークフローは変わりません。引き続き Claude Code、Codex、または Xcode の Intelligence エージェントを MCP で操作し、CLAUDE.md を作成し、hooks で破壊的な操作を制限します。変わるのは、エージェントがコードを書く対象領域です。iOS 27 にはエージェントに関連する新しいフレームワークが複数追加されています。2026年6月より前に学習されたモデルはそれらの存在を知らないため、コーディングエージェントに明示的に指定することが実践的です。iOS 26 は引き続きリリース済みのバージョンです。以下は、iOS 27 ベータ版の SDK を対象にビルドする際の指針として扱ってください。
エージェントに関連する iOS 27 の対象領域と、それぞれの詳細な参照先を以下に示します。
- Foundation Models に tool-calling の制御機能が追加されました。
GenerationOptions.ToolCallingModeを使用すると、オンデバイスモデルがツールを呼び出す積極性をリクエストごとに制御できます。また、フレームワークは最初の呼び出し後にモードを切り替え、リクエストによるツール操作を制限できます。Vision フレームワークには、認識コードを書かずにLanguageModelSessionへ追加できる既製のOCRToolとBarcodeReaderToolが追加されています。Foundation Models in iOS 27: Tool-Calling Control をご覧ください。12 - App Intents が 30 秒の壁を突破しました。 進行状況の報告が必要な
LongRunningIntent(performBackgroundTask(options:operation:)経由)により、同期、ファイル操作、オンデバイス推論のために intent のバックグラウンド実行時間を延長できます。SyncableEntityはAppEntityにデバイス間で共有される ID を与え、IndexedEntityQueryは Spotlight インデックスの修復をクエリに要求できるようにします。App Intents in iOS 27: Background, Sync, Spotlight をご覧ください。13 - Core AI は Apple Silicon 上でモデルを実行するための新しいフレームワークです。 Apple のシステムモデルではなく独自のモデルを持ち込む場合に、Foundation Models より下位の層として使用します。Core AI: Running Models on Apple Silicon をご覧ください。14
- Evaluations はモデル品質のための XCTest です。 テストスイートの一部としてモデル出力の品質を測定する、新しいフレームワーク(macOS 27)です。エージェントの支援で構築した AI 機能をリリースするために欠けていた要素を補います。Evaluations: XCTest for Model Quality をご覧ください。15
- SwiftData、HealthKit、SwiftUI も進化しています。 SwiftData には iOS 27 で観測と履歴が追加され、HealthKit にはワークアウトゾーンと新しい型が追加されます。SwiftUI の iOS 27 における追加機能も、例年どおり幅広い領域に及びます。SwiftData in iOS 27、HealthKit in iOS 27、What’s New in SwiftUI for iOS 27 をご覧ください。16
iOS 27 開発向けのツールチェーンは Xcode 27 ベータです。 Xcode 27 は WWDC 初日(6月8日、build 27A5194q)にベータ版として公開され、8月10日時点で beta 5(27A5237l)です。Swift 6.4 と、iOS 27 / iPadOS 27 / tvOS 27 / watchOS 27 / macOS 27 / visionOS 27 の SDKs が含まれており、macOS Tahoe 26.4 以降が必要です。18 エージェントのワークフローでは、リリースノートのうち 4 項目が重要です。Coding Intelligence には plan mode が追加されました。リリースノートでは「Implement the plan?」確認バーに関する既知の問題(178673449)として示されているため、プランを確認または却下する前にエージェントのストリーミングが終わるのを待ってください。RenderPreview MCP ツールは Preview グループをレンダリングできるようになり(174692209)、異なるローカライゼーションで UI をプレビューできます(181040291)。エージェント向けの「Prepare Project for Localization」ツールは、ソースに出現しなくなったため削除された String Catalog キーを報告するようになりました(179755385)。また、アプリが Xcode 26.4 以前でビルドされている場合、Address Sanitizer は 27.0 ターゲットで起動に失敗する可能性があります。ASan 実行には Xcode 26.5 以降を使用してください(178072780)。18 Beta 5 では、ここで重要な項目がさらに 2 つ追加されています。エージェントが watchOS アプリを検証できるようになり、「Digital Crown の回転と押下、さらにサイドボタンおよび Action ボタン(Apple Watch Ultra)の押下」を含めて操作できます(181147968)。これは、Apple のエージェントが watch アプリの物理入力を操作できる初めての機能であり、このガイドで扱う視覚的検証のギャップを一部解消します。また Apple は、Xcode を開かずに利用できる MCP サーバーをプレビューしました。Apple の MCP サーバーについては、以下のセクションをご覧ください。22 MCP のツール群もベータに追随しています。XcodeBuildMCP v2.7.0(2026-07-23)では、Device Hub を通じて UI 自動化ツールが Xcode 27 シミュレータで完全に動作するようになりました。シミュレータウィンドウの起動やキーボード操作も含まれます。このリリース以前は、ランタイム UI 自動化は Xcode 26 シミュレータに対してのみ信頼できるものであり、iOS 27 ベータでのエージェント主導 UI 検証は手動作業になっていました。21
運用上の教訓は、このガイド全体で述べているものと同じです。エージェントがコードを書きますが、不足している知識を与えるのはあなたです。iOS 27 ベータでは、これらのフレームワークをプロンプトまたは CLAUDE.md で明示し、Apple のドキュメントへエージェントをリンクする必要があります。そうしなければ、モデルは各 API の iOS 26 における形を参照してしまいます。このガイドの他の内容(runtimes、MCP、hooks、failure modes)は、iOS 27 開発でも変わらず適用できます。
ポートフォリオ:8 アプリ、293 ファイル
設定に入る前に、このガイドの基となった内容をご紹介します。これらは玩具的なプロジェクトではありません。5 つの Apple フレームワーク、3 つのプラットフォームにまたがり、14 ファイルのワークアウトトラッカーから 63 ファイルのマルチプラットフォーム瞑想タイマーまで、iOS 開発の複雑さを幅広くカバーしています。
| アプリ | スタック | ファイル | 複雑さ |
|---|---|---|---|
| Banana List | SwiftUI + SwiftData + iCloud Drive sync + MCP server for Claude Desktop | 53 | 完全な CRUD、iCloud 同期、アプリのデータを Claude Desktop に公開するカスタム MCP サーバー |
| Ace Citizenship | SwiftUI 学習アプリ + FastAPI バックエンド | 26 | クライアント・サーバー、REST API 統合、クイズエンジン |
| TappyColor | SpriteKit カラーマッチングゲーム | 30 | ゲームループ、物理演算、タッチ処理、パーティクルエフェクト |
| Return | Zen 瞑想タイマー — iOS 26+、watchOS、tvOS | 63 | HealthKit、Live Activities、Watch の拡張ランタイム、TV のフォーカスナビゲーション、iCloud セッション同期 |
| amp97 | Metal shaders + オーディオビジュアライゼーション | 41 | カスタム Metal レンダーパイプライン、オーディオ分析、リアルタイム GPU compute |
| Reps | SwiftUI + SwiftData ワークアウトトラッキング | 14 | 最小実用アプリ、クリーンな SwiftData パターン |
| Water | SwiftUI + SwiftData + Metal + HealthKit 水分補給トラッキング | 34 | Metal 流体シミュレーション、HealthKit の飲水量記録、ウィジェット |
| Starfield Destroyer | SpriteKit + Metal 宇宙シューティングゲーム | 32 | 99 レベル、8 機の船、Game Center リーダーボード、Metal ポストプロセシング |
ファイル数が重要な理由: エージェントの有効性は、プロジェクト規模ではなくプロジェクトの可読性と相関します。Return(63 ファイル)は、amp97(41 ファイル)より優れたエージェント出力を生みます。Return にはファイル注釈、アーキテクチャ図、明示的なパターンを含む詳細な CLAUDE.md があるためです。amp97 の Metal shaders は、ドキュメントの品質にかかわらず、エージェントが推論するには本質的により難しいものです。
前提条件
iOS 開発向けのエージェント runtime を設定する前に、以下を確認してください。
App Store Connect の期限: 2026-04-28 以降、App Store Connect へアップロードするアプリは、iOS 26、iPadOS 26、tvOS 26、visionOS 26、または watchOS 26 向けの SDKs を使用し、Xcode 26 以降でビルドする必要があります。26(macOS の提出にはこの要件は適用されません。)チームがまだ Xcode 16.x を使用している場合、このガイドのエージェント支援ツールチェーンは移行を促す契機にもなります。いずれにしても、以下の MCP サーバーはいずれも Xcode 26.3+ なしでは動作しません。
必須:
- macOS 15+(Sequoia)または macOS Tahoe(Xcode 26.6 には macOS Tahoe 26.2+、Xcode 27 ベータには Tahoe 26.4+ が必要です)
- Xcode 26.3+ をインストール・設定済みであること(xcrun mcpbridge の最低要件)。Xcode 26.6+ を推奨します。 Xcode 26.6(2026-06-25、build 17F113)は最新の安定版で、エージェントに関連する Coding Intelligence の変更を 3 つ導入しています。コーディングアシスタントプロバイダーとしての Google Gemini、Agent Client Protocol(ACP)サポート、preview MCP ツールにおける light/dark、orientation、type sizes のバリアントレンダリングです。また、エージェントのターン中に起きる 2 件のクラッシュと、エージェントが質問した際のハングも修正され、Swift 6.3 と iOS 26.5 世代の SDKs も含まれます。17 26.5 のワークフロー強化(コーディングアシスタントのメッセージキューイングと明確化質問のサポート)と、26.4 の Swift Testing 画像添付、記録済み issue の重大度、crashlog を伴う UI テストクラッシュ警告、String Catalog エディタの改善もすべて引き継がれています。2728 以前の安定版は、26.5(2026-05-11、build 17F42)と 26.4.1(2026-04-16、build 17E202)です。29
- 少なくとも 1 つの iOS Simulator runtime をインストール済みであること
- Claude Code 用の Anthropic API アカウント、または Codex 用の OpenAI アカウント
推奨:
- SwiftFormat をインストール済みであること(brew install swiftformat)— format-on-save hooks で使用します
- SwiftLint をインストール済みであること(brew install swiftlint)— 任意ですが、スタイルの強制に役立ちます
- ターミナルに慣れていること — 3 つの runtime はすべてコマンドラインから操作するか、コマンドラインと統合されます
Xcode のインストールを確認する:
# Check Xcode version
xcodebuild -version
# Expected: Xcode 26.3 or later (26.6+ recommended)
# Check available simulators
xcrun simctl list devices available
# Expected: at least one iPhone simulator
# Verify xcrun mcpbridge is available
xcrun mcpbridge --help
# Expected: usage information (not "command not found")
xcrun mcpbridge が「command not found」を返す場合は、Xcode 26.3 以降が必要です。App Store または developer.apple.com から Xcode をインストールまたは更新してください。注意:xcode-select --install でインストールされるのは Command Line Tools のみで、mcpbridge は含まれません。完全版の Xcode.app が必要です。
iOS向けの3つのエージェントランタイム
iOSコードの作成、ビルド、テストを行えるランタイムは3種類あります。これらは互換ではありません。それぞれに異なる強み、異なるMCP統合パターン、そして最適な用途があります。
1. Claude Code CLI
概要: Anthropicのターミナルベースのエージェント型コーディングアシスタントです。コードベースを読み取り、コマンドを実行し、ファイルを変更し、MCPを介して外部ツールに接続します。7
MCP統合: XcodeBuildMCPとAppleのXcode MCPの両方を完全にサポートしています。エージェントはMCPプロトコル経由でツールを検出し、構造化されたパラメータで呼び出します。2つのサーバーを合わせて82 + 20のツールがあります。
セットアップ:
# Install Claude Code (if not already installed)
claude --version # verify installation
# Add XcodeBuildMCP (82 tools — builds, tests, simulators, debugging)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Add Apple Xcode MCP (20 tools — file ops, diagnostics, Swift REPL, previews)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
代替手段 — xcodebuildmcp init自動インストーラー(v2.1.0+、2026年2月23日):
手動でのMCP設定を省きたい場合、XcodeBuildMCP v2.1.0+にはinitサブコマンドが含まれています。Claude Code、Cursor、またはCodexを自動検出し、エージェントスキルとMCP設定を1ステップでインストールします。
xcodebuildmcp init
# Or without a global install:
npx -y xcodebuildmcp@latest init
フラグ:--print(未対応クライアント向けに設定をstdoutへ出力)、--uninstall(削除)。どのMCPサーバーをどのスコープで接続するかを明示的に制御したい場合は、これをスキップしてください。上記の手動claude mcp add呼び出しなら、それを制御できます。30
最適な用途: 新機能の実装、複数ファイルにまたがるリファクタリング、複雑な問題のデバッグ、ビルド・テスト・修正ループの自律実行といった、深い実装セッションです。Claude Codeの1Mコンテキストウィンドウ(Opus 5使用時)なら、小〜中規模のiOSプロジェクトの大半を作業メモリに保持できます。私の経験では、ファイルサイズにもよりますが、概ね最大50ファイルです。25
一般的なセッション:
You: Add a new SettingsView with toggles for notifications and haptic feedback.
Use the existing Settings.swift pattern from TimerManager.
Build for simulator after implementation and fix any errors.
Claude: [reads Settings.swift, TimerManager.swift, existing views]
[creates SettingsView.swift]
[calls build_sim via MCP]
[reads structured error: missing import HealthKit]
[fixes import]
[calls build_sim again — success, 0 errors, 1 warning]
[calls test_sim — all tests pass]
MCP以前のワークフローとの重要な違いは、エージェントが手動でビルドしたりエラー出力を貼り付けたりするよう求めない点です。ビルド・エラー・修正のループは自律的に進みます。
2. Codex CLI
概要: OpenAIのターミナルベースのコーディングエージェントです。概念的にはClaude Codeと似ていますが、OpenAIのCodexモデル上で動作し、権限モデルが異なります。現在のラインアップは、GPT-5.6 Sol(フラッグシップ、複雑なコーディングに最も強い)、GPT-5.6 Terra(日常用途向けのバランスの取れたデフォルト)、GPT-5.6 Luna(高速かつ最安)で、GPT-5.3 Codex Sparkはテキスト専用のリサーチプレビューです。GPT-5.4とGPT-5.4-miniは2026年8月31日にCodexから廃止されるため、それらの設定はそれぞれTerraとLunaへ移行してください。23
MCP統合: Codexはcodex mcp addコマンドを介してMCPをサポートします。AppleのXcode MCPは直接動作します。
# Add Apple Xcode MCP to Codex
codex mcp add xcode -- xcrun mcpbridge
XcodeBuildMCPも、同じnpxコマンドを通じてCodexで動作します。
# Add XcodeBuildMCP to Codex
codex mcp add XcodeBuildMCP -- npx -y xcodebuildmcp@latest mcp
最適な用途: ヘッドレスのバッチ処理、CI/CD統合、異なるモデルファミリーからセカンドオピニオンを得たいタスクです。Codexのサンドボックスモードは隔離された環境でコードを実行するため、状態を変更するテストスイート実行のような破壊的操作に役立ちます。
Claude Codeとの主な違い:
- ClaudeモデルではなくOpenAIモデルを使用します
- コンテキストウィンドウのサイズとトークン経済性が異なります
- サンドボックス優先の権限モデルです(デフォルトでより制限的)
- MCPエコシステムが小規模です(テスト済みのコミュニティサーバーが少ない)
- Hooksシステムは利用可能です(v0.119.0+)が、Claude Codeのものほど成熟していません。イベントタイプが少なく、条件付き
ifフィールドもありません
iOSでClaude CodeよりCodexを使うべき場合:
モデルの多様性が欲しいときはCodexを使ってください。1つ目のエージェントが書いたコードを2つ目のエージェントでレビューすると、異なる種類のエラーを見つけられます。collab workflow(Claudeが実装し、Codexがレビュー)は、1つのモデルファミリーでは正しく見えるSwiftUIパターンにも、別のモデルが見つけられる微妙な問題があるため、iOSで効果的です。Metalシェーダーと並行処理パターンは、特にデュアルモデルレビューの恩恵を受けます。
3. Xcodeネイティブエージェント
概要: AppleはXcodeのIntelligenceパネルにAIコーディングエージェントを直接統合しました。Xcode 26.3以降、Xcode Settings > IntelligenceでClaude AgentとCodexをインテリジェンスプロバイダーとして設定できます。10 Xcode 26.6では対応プロバイダーが拡大しています。Google Geminiがコーディングアシスタントで利用可能になり(171990272)、XcodeにはAgent Client Protocol(ACP)サポートも追加されました(178294840)。つまり、当初は2プロバイダー統合として始まったものが、現在は3プロバイダーと、ACP互換エージェントをIntelligenceパネルに接続できるオープンプロトコルへと広がっています。17
セットアップ:
- Xcode 26.3+を開きます
- Settings > Intelligenceへ移動します
- 新しいプロバイダーを追加します。
- Claudeの場合:「Claude Agent」を選択し、Anthropic APIキーを入力します
- Codexの場合:「Codex」を選択し、OpenAI APIキーを入力します
- Geminiの場合:「Google Gemini」を選択します(Xcode 26.6+)
- それ以外の場合:ACP互換エージェントを接続します(Xcode 26.6+)
- エージェントがIntelligenceサイドバーに表示され、インラインで呼び出せるようになります
最適な用途: すばやいインライン編集、エージェントレベルの推論を伴うコード補完、Xcodeから離れたくない開発者向けです。ネイティブ統合により、エージェントはMCPブリッジなしで、開いているファイル、ビルドターゲット、スキーム設定などXcodeのプロジェクトコンテキストへ直接アクセスできます。
CLIエージェントと比べた制限事項 — Xcode 26.xの場合:
- Hooksシステムがないため、保存時フォーマットの強制や.pbxproj書き込みのブロックはできません
- CLAUDE.mdを読み込みません。エージェントはプロジェクトレベルの設定ファイルを読みません
- 自律性が限定的です。エージェントはプロジェクト全体ではなく、現在のファイルまたは選択範囲を対象に動作します
- サブエージェントの委任がありません。複雑な複数ステップのタスクを並列化できません
- MCPサーバー設定がありません。エージェントはXcode組み込みツールだけを使用します
Xcode 27では、このリストの大半が無効になります。 beta 1(6月8日)以降、Xcodeのエージェントはインラインアシスタントではなく拡張プラットフォームです。22
- プラグイン:「Xcodeのエージェントは、スキル、MCPサーバー、ACPエージェント設定を含むプラグインで拡張できるようになりました。スキルは補完サポート付きのスラッシュコマンドとして呼び出せます。」(178289210)— つまり、「組み込みツールのみ」と「MCP設定なし」という制限は解消されました。
- Simulator制御:エージェントは「Simulatorの起動、アプリのインストールと起動、タッチイベントの合成、UI動作を検証するスクリーンショットのキャプチャ」が可能になりました(175179787)。beta 5ではwatchOSハードウェア入力も操作できます(181147968)。
- デバッガーアクセス:Xcode MCPサーバーには、実行状態の操作、デバッガーコンソールの読み取り、スキームと実行先の切り替え、「ビルド設定、コンパイラフラグ、エンタイトルメント、Info.plistキー」の検査・変更を行うツールが追加されました(176935844)。
- コーディングエージェントとそのエージェントが起動するプロセスによるファイルシステムアクセスを「監視・制御するファイルシステムセキュリティ層」(178289431)に加え、ファーストクラスの計画機能(172857081)、クラッシュ、ハング、エネルギー、起動の問題を対象としたプロジェクトインサイト(177568662)が提供されます。
176935844から直接導かれる1つの警告: Xcodeのエージェントは、ビルド設定、エンタイトルメント、Info.plistキーを編集できるようになりました。このガイドがPreToolUse hookで構築する.pbxproj保護は、Xcode内では適用されません。hookはAppleの設定ではなく、CLIエージェントの設定にあるためです。そのhookを安全策として頼りにしている場合、Intelligenceパネルにはその権限が及ばないことを理解しておいてください。
Xcodeネイティブエージェントを使うべき場合:
ターミナルへ切り替えるのがオーバーヘッドとなる、素早くスコープの限定された編集に適しています。「このモデルに計算プロパティを追加する。」「この関数のユニットテストを書く。」「このビューを@Observableを使うようリファクタリングする。」といった、1〜2ファイルに触れ、ビルド・テストサイクルを必要としないタスクです。
ビルド、テスト、複数ファイルのリファクタリング、自律的なエラー修正が必要な場合は、MCPを備えたCLIエージェントを使用してください。
ランタイム比較マトリクス
| 機能 | Claude Code CLI | Codex CLI | Xcodeネイティブ(26.x → 27) |
|---|---|---|---|
| MCPサポート | 完全(102ツール) | 完全(102ツール) | 26.x:組み込みツールのみ、27:プラグイン経由のMCPサーバー22 |
| Hooksシステム | はい(成熟) | はい(基本、v0.119.0+) | いいえ |
| CLAUDE.md / プロジェクト設定 | はい | codex.md相当 | いいえ |
| 自律的なビルド・テスト・修正 | はい(MCP経由) | はい(MCP経由) | 26.x:部分的(インラインのみ)、27:Simulatorを起動してUIを検証22 |
| サブエージェントの委任 | はい(最大10並列) | いいえ | いいえ |
| コンテキストウィンドウ | 1Mトークン(Opus 5) | モデルにより異なる | プロバイダーにより異なる |
| 複数ファイル操作 | コードベース全体へのフルアクセス | コードベース全体へのフルアクセス | 26.x:現在のファイル / 選択範囲、27:計画機能によるプロジェクト全体22 |
| .pbxproj保護 | Hooks経由 | 手動 | 該当なし(Xcodeをネイティブに使用) |
| 保存時フォーマット | PostToolUse hooks経由 | 外部ツール | Xcode設定 |
| オフライン機能 | いいえ | いいえ | いいえ |
| コストモデル | Anthropic API利用量 | OpenAI API利用量 | プロバイダーAPI利用量 |
推奨: Claude Code CLIを主要ランタイムとして使用してください。素早いインライン編集にはXcodeネイティブエージェントを使います。レビュー工程とバッチ操作にはCodex CLIを使ってください。3者は競合するのではなく、互いを補完します。
MCP のセットアップ:完全な設定
MCP(Model Context Protocol)は、エージェントを「Swiftを書いてビルドできることを願う」状態から、「Swiftを書き、ビルドし、構造化されたエラーを読み取り、修正する」状態へ変えるものです。2 このセクションでは、ブログ記事11 より詳しく、両方のサーバー、すべてのインストール方法、検証、そしてツールが実際に使われるようにするエージェント設定を扱います。
XcodeBuildMCP:ヘッドレスiOS開発のための82ツール
XcodeBuildMCP は、xcodebuild、xcrun simctl、LLDBを82の構造化されたMCPツールにまとめています(公開されているツール一覧はv2.6.2からv2.7.0まで変わらないことを確認済み)。これらは12のワークフローカテゴリーに分類されています。31921 プロジェクトの正式な拠点はgetsentry GitHub組織です。Sentryが保守しており、元のcameroncooke/XcodeBuildMCP URLは現在そこへリダイレクトされます。古い記事が旧アドレスを参照している場合に重要です。21 Xcodeを起動せずに動作し、ビルド・テスト・デバッグのサイクル全体をAppleのコマンドラインツール経由でヘッドレスに実行できます。知っておくべきツール一覧の注意点は2つあります。デフォルトのstdioセッションでは、シミュレーターワークフローの約24ツールだけが公開され、残りはエージェントのコンテキストに入れません。さらに読み込むには、XCODEBUILDMCP_ENABLED_WORKFLOWS に以下の表のカテゴリ名をカンマ区切りで指定します。また、同じエンジンはCLIとしても提供されています(xcodebuildmcp tools は100コマンド、うち72が正規コマンドと報告します)。MCPなしで同じ操作を使いたい場合に便利です。9
インストールオプション:
# Option 1: Via npx (recommended — always uses latest version)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Option 2: Via Homebrew (pinned version, manual updates)
brew install xcodebuildmcp
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- xcodebuildmcp mcp
# Option 3: Project-scoped (omit -s user)
claude mcp add XcodeBuildMCP \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
-s user フラグを使うと、すべてのプロジェクトでサーバーをグローバルに利用できます。プロジェクト単位でインストールする場合は省略してください(WebプロジェクトではなくiOSプロジェクトでだけMCPを使いたい場合に便利です)。
-e XCODEBUILDMCP_SENTRY_DISABLED=true 環境変数は、クラッシュレポートのテレメトリーを無効にします。XcodeBuildMCPにはデフォルトでSentryが含まれており、ファイルパスを含むエラーデータを送信します。プロジェクトへ診断情報を提供したい場合を除き、オプトアウトしてください。1
ツール一覧(12ワークフローカテゴリー、全82ツール。カテゴリごとの代表的なツール):
| カテゴリー | ツール | 機能 |
|---|---|---|
| project-discovery | discover_projs, list_schemes, show_build_settings, get_app_bundle_id |
.xcodeproj/.xcworkspaceファイルを検出し、スキームを一覧表示して、ビルド設定を確認します |
| simulator | build_sim, build_run_sim, test_sim, install_app_sim, launch_app_sim |
ファイルと行ごとに構造化されたエラー/警告出力でビルド・テストを行い、シミュレーターへアプリをインストールして起動します |
| simulator-management | list_sims, boot_sim, open_sim, erase_sims, set_sim_appearance, set_sim_location, session_set_defaults |
シミュレーターを起動、消去、設定します(外観、位置、ステータスバー) |
| device | build_device, test_device, list_devices, install_app_device, launch_app_device |
実機でのビルド、テスト、デプロイ、管理を行います |
| macos | build_macos, build_run_macos, test_macos |
Macターゲットに対して同じビルド・テストループを実行します |
| swift-package | swift_package_build, swift_package_test, swift_package_run |
.xcodeprojなしでSwiftPMのビルド/テスト/実行を行います |
| coverage | get_coverage_report, get_file_coverage |
.xcresultバンドルからターゲット単位および関数単位のカバレッジを取得します |
| debugging | debug_attach_sim, debug_breakpoint_add, debug_stack, debug_variables, debug_lldb_command, debug_continue, debug_detach |
ブレークポイントと変数の確認を含む完全なLLDB統合を提供します |
| ui-automation | snapshot_ui, wait_for_ui, batch, tap, drag, swipe, type_text, gesture, screenshot, record_sim_video |
安定した要素参照を使った実行時UI自動化(v2.6.0以降)に加え、視覚的なキャプチャを行います |
| project-scaffolding | scaffold_ios_project, scaffold_macos_project |
テンプレートから新しいiOS/macOSプロジェクトを作成します |
| utilities | clean |
ビルド生成物をクリーンアップします |
| xcode-ide | xcode_ide_list_tools, xcode_ide_call_tool |
XcodeBuildMCP経由でXcode-IDE専用のMCPツールを検出・呼び出しします(後述) |
日常作業で特に重要なツール:
-
build_sim— 何百回も呼び出すことになります。エラーをファイル、行、重大度ごとに分類したJSONを返します。エージェントはエラーを読み、ファイルへ移動して、何も操作せずに修正します。 -
test_sim— テストメソッドごとの結果を返します。エージェントは単に「テストが失敗した」と捉えるのではなく、どのテストがなぜ失敗したかを正確に把握できます。 -
list_sims+boot_sim—xcrun simctlフラグを覚えなくてもシミュレーターを管理できます。エージェントは利用可能なランタイムを検出し、適切なデバイスを選びます。 -
discover_projs+list_schemes— プロジェクトの調査です。エージェントはスキーム名やワークスペース構造を推測する必要がありません。 -
debug_attach_sim+debug_stack+debug_variables— リモートLLDBデバッグです。デバッガーを開かなくても、エージェントはブレークポイントの設定、変数の確認、コードのステップ実行を行えます。
v2.6.0で変わったこと(2026-06-01)— 実行時UI自動化:
v2.6.0では、UI自動化がワンショットのスクリーンショットではなく、再利用可能なコンテキストを中心とする仕組みに再構築されました。19 snapshot_ui は安定した要素参照と画面ハッシュを返すようになり、sinceScreenHash を受け取れるため、画面に変化がない場合、エージェントは完全なスナップショットを省略できます。3つの新ツールがこのループを完成させます。wait_for_ui は、エージェントがsleepで推測する代わりに、条件が満たされるまでポーリングします(存在、有効状態、フォーカス、可視テキスト、レイアウトの安定)。batch は要素参照による一連の操作を1回の呼び出しで実行します。drag はシートやリストスクロール向けに、要素参照のドラッグジェスチャーを実行します。type_text には、フィールドの値を追記ではなく置き換える replaceExisting が追加されました。候補コントロールはアクセシビリティデータに基づいてランク付けされ、構造化結果には nextSteps のヒントも含まれるようになりました(結果スキーマはこのリリースでv2になり、v2.7.0ではビルド/テスト結果が schemaVersion: 3 に移行しています。後述)。XCODEBUILDMCP_HEADLESS_LAUNCH=true を設定すると、macOSのフォーカスを奪わずにバックグラウンドでアプリを起動できます。エージェントセッションを実行したままにできるか、Simulatorウィンドウを何度も前面へ引っ張られるかの差になります。決定論的なWeatherアプリのタスクにおいて、プロジェクト自身のベンチマークでは、v2.6以前のフローと比べて経過時間が約70%短縮、トークンが68%減少、ツール呼び出しが76%減少したとされています。独立した測定ではなくプロジェクト側の数値ですが、その仕組み(変化のないスナップショットの省略、同一画面上の操作のバッチ化)こそがUI自動化でトークンを消費する箇所です。19
v2.7.0で変わったこと(2026-07-23)— Xcode 27シミュレーター、スキーマv3、スキーム設定を尊重するビルド:
v2.7.0のリリースは2.6.0より小規模ですが、アップグレード前に知っておくべき破壊的変更と動作変更が1つずつあります。21 主な変更点は、UI自動化ツールがDevice Hubを通じてXcode 27シミュレーターで完全に動作するようになったことです。シミュレーターウィンドウの起動やキーボード操作にも対応し、実行時UI自動化がXcode 26シミュレーターでしか信頼できなかった差を埋めます。破壊的変更: ビルドおよびテストツールは schemaVersion: 3 の構造化結果を返すようになりました(2.6.0以降はv2でした)。バージョン2に固定して結果を検証・解析するものを作成している場合は更新が必要です。動作変更: configuration を省略した場合、ビルド、テスト、クリーン、アプリパス取得ツールは常にDebugをデフォルトにするのではなく、スキームアクションの設定を尊重するようになりました。スキームのTestアクションがReleaseに設定されている場合、指定なしのtest_simはReleaseをビルドするため、ワークフローが特定の設定に依存する場合は configuration を明示的に渡してください。小さいながら有用な変更として、再利用可能な .xctestproducts テスト準備パッケージにより、毎回新しい .xcresult を生成しつつ再ビルドなしでテストを再実行できます。セッションデフォルトの extraArgs では、共通の xcodebuild フラグを呼び出しごとに繰り返さず、セッションごとに一度設定できます。新しい xcodebuildmcp purge CLIコマンドは、XcodeBuildMCPのワークスペースストレージを報告・クリーンアップします(デフォルトではdry-runで、削除には明示的なオプトインが必要です)。また、ツールが利用可能になるまでMCPクライアントが10〜17秒待機する問題も修正されました。この問題により、短いヘルスチェックで接続失敗と報告される場合がありました。21
Apple Xcode MCP:Xcodeへ橋渡しする20ツール
AppleのMCPサーバーは、xcrun mcpbridge を通じてXcode 26.3に付属しています。4 XPC(Appleのプロセス間通信フレームワーク)を介して実行中のXcodeプロセスと通信し、CLIツールではアクセスできない内部状態を公開します。5
インストール:
# Standard installation (global)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
# For Codex CLI
codex mcp add xcode -- xcrun mcpbridge
Xcode 26.3以降と、実行中のXcodeプロセスが必要です。 Xcodeが開かれていない場合、このサーバー経由のすべてのMCP呼び出しは失敗またはハングします。XcodeBuildMCPにはこの制限がありません。
Xcode 27 beta 5では、この制約を回避する方法がプレビューされています。 Appleは「開いているXcodeワークスペースを必要とせずに動作する新しいMCPサーバーエクスペリエンス」を追加しました。sudo xcrun mcp-server enable で有効化し、xcrun mcp-server status で確認できます。同じプレビューでは、コード署名されたエージェントに対して、都度再承認するのではなく、ディレクトリツリー内で作業する持続的な権限を付与できます。無人実行では、sudo xcrun mcp-server enable --unsafe-always-allow-all-agents によってすべてを事前承認できます。Appleはこれを「デスクで使用する際に推奨される設定ではない」と明言しています。私も同意します。意図せず公開したディレクトリからエージェントを守る承認ステップがなくなるためです。全体を初期プレビューとして扱い、プレビューが終了するまではヘッドレスの経路としてXcodeBuildMCPを維持してください。22
ツール一覧(5カテゴリ、全20ツール):
| カテゴリー | ツール | 機能 |
|---|---|---|
| ファイル操作 | XcodeRead, XcodeWrite, XcodeUpdate, XcodeGlob, XcodeGrep |
Xcodeプロジェクトのコンテキスト内でファイルを読み書きします |
| ビルドとテスト | BuildProject, GetBuildLog, RunAllTests, RunSomeTests |
Xcodeの内部ビルドシステムでビルド・テストします |
| 診断 | XcodeListNavigatorIssues, XcodeRefreshCodeIssuesInFile |
リアルタイムのコード診断を行います(単なるビルドエラーではありません) |
| コードとドキュメント | ExecuteSnippet, DocumentationSearch |
Swift REPLの実行とAppleドキュメントの検索を行います |
| プレビュー | RenderPreview |
ヘッドレスでSwiftUIプレビューをレンダリングします |
Apple MCPに固有のツール(XcodeBuildMCPでは利用不可):
-
DocumentationSearch— WWDCセッションを含むAppleの開発者向けドキュメントを検索します。Apple APIに関する質問では、Web検索より高速かつ信頼できます。「HKQuantityType(.dietaryWater)は有効ですか?」と尋ねれば、ソースから確実な回答を得られます。 -
ExecuteSnippet— プロジェクトのコンテキスト内でSwift REPLを実行します。フルアプリをビルドせずに、エージェントはAPIの動作確認、型変換のテスト、式の検証を行えます。 -
RenderPreview— SwiftUIプレビューをヘッドレスでレンダリングします。ビューがエラーなくレンダリングされるかを確認できますが、視覚的な正しさは評価できません(レンダリング結果は視覚的に確認されるのではなくデータとして返されます)。Xcode 26.6以降、プレビューMCPツール(26.6のリリースノートでは「Preview Snapshot」と呼ばれます)は、ライト/ダーク外観、縦/横方向、文字サイズのオーバーライドというバリアントをレンダリングします(178831772)。そのため、エージェントは1回で複数の外観にわたってビューを検証できます。17 Xcode 27 betaではさらに拡張され、Previewグループのレンダリングと別ローカリゼーションでのプレビューにも対応しています。18 -
XcodeListNavigatorIssues— ビルドエラーだけでなく、Xcodeのアナライザーによるリアルタイム診断を返します。未使用変数、潜在的なretain cycle、ビルドシステムが表示しない非推奨警告などの問題を検出します。
両方のサーバーが必要な理由
ビルドとテストは重複していますが、本質的には異なります。
┌─────────────────────────────────────────────────────────────────┐
│ MCP TOOL COVERAGE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ XcodeBuildMCP (82 tools) Apple Xcode MCP (20 tools) │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Standalone │ │ Requires Xcode │ │
│ │ (no Xcode process) │ │ (XPC bridge) │ │
│ │ │ │ │ │
│ │ ✓ Simulators │ BOTH │ ✓ Documentation │ │
│ │ ✓ Real devices │ ┌─────┐ │ ✓ Swift REPL │ │
│ │ ✓ LLDB debugging │ │Build│ │ ✓ SwiftUI previews │ │
│ │ ✓ UI automation │ │Test │ │ ✓ Live diagnostics │ │
│ │ ✓ Project scaffold │ └─────┘ │ ✓ Analyzer issues │ │
│ │ ✓ Screenshot │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
XcodeBuildMCPを使う場面: ビルド・テスト・デバッグのサイクルです。Xcodeを開かずに動作し、使用するシステムメモリが少なく、シミュレーターとデバイスの管理機能もより充実しています。これが主なビルドツールです。
Apple Xcode MCPを使う場面: ドキュメントの検索、Swift REPLでの検証、SwiftUIプレビューのレンダリング、リアルタイム診断です。これらの機能が必要なセッションではXcodeを開いたままにしてください。
実際には: MCP呼び出しの約90%でXcodeBuildMCPを使い、Apple Xcode MCPはドキュメントとREPLの検証に使っています。ビルドとテストでは、Xcodeプロセスのオーバーヘッドがなく高速で、XPC依存もなく信頼性が高いため、エージェントはXcodeBuildMCPをデフォルトにします。
2サーバーという枠組みは緩和されつつあります。 XcodeBuildMCP 2.6.xでは、xcode-ide プロキシカテゴリが追加されています。xcode_ide_list_tools はXcode-IDE専用のMCP機能を検出し、xcode_ide_call_tool はそれらを呼び出します(xcode_tools_documentationsearch のように xcode_tools_* 名で公開されます)。そのため、XcodeBuildMCPの登録1つからAppleのIDE側ツールにもアクセスできるようになりました。19 重要な制約は変わりません。プロキシ経由の呼び出しにも、直接のxcrun mcpbridge登録とまったく同じく、実行中のXcodeプロセスが必要です。Appleのツールをエージェントのツール一覧で第一級に扱いたい場合は両方のサーバーを登録しておいてください。プロキシは、サーバー登録を1つにし、IDEの読み取りをたまにしか行わない場合に最も役立ちます。
検証
両方のサーバーをインストールしたら、接続されていることを確認します。
# List all configured MCP servers
claude mcp list
# Expected output includes:
# XcodeBuildMCP: npx -y xcodebuildmcp@latest mcp - Connected
# xcode: xcrun mcpbridge - Connected
サーバーが「Disconnected」と表示される、または表示されない場合:
- XcodeBuildMCPが接続しない: Node.jsがインストールされていることを確認してください(
node --version)。npxコマンドにはNode.js 18以降が必要です。 - Apple Xcode MCPが接続しない: Xcode 26.3以降がインストールされ、ターミナルで
xcrun mcpbridgeコマンドが動作することを確認してください。ライセンス契約に同意するため、少なくとも一度Xcodeを開いてください。 - どちらも表示されない: Claude Codeを再起動してください(新しいターミナルで
claudeを実行します)。セッション途中で登録したMCPサーバーは、再起動するまで表示されない場合があります。
エージェントにMCPの使い方を教える
MCPサーバーをインストールすることは必要ですが、それだけでは十分ではありません。明示的な指針がないと、エージェントはBash経由でxcodebuildを実行する方法に戻ることがあります。その出力は構造化されておらず、コンテキストトークンを無駄にします。また、AppleドキュメントにWeb検索を使うこともあります。こちらは低速で信頼性も下がります。
これをCLAUDE.mdまたはエージェント定義に追加してください。
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim` (NOT `xcrun simctl` via Bash)
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
- **Previews**: `RenderPreview` for headless SwiftUI verification
MCP returns structured JSON. Bash returns unstructured text.
Structured data means fewer tokens consumed and better error diagnosis.
この指針により、エージェントは最初にMCPツールを選ぶようになります。ない場合、エージェントがBashで長いxcodebuildコマンドを組み立て、出力の解析に数千のコンテキストトークンを消費し、実際のエラーを誤認することもあります。6
XcodeBuildMCP v2.7.0の動作変更のうち1つは、このセクションの考え方に含めるべきです。configuration を省略すると、ビルド、テスト、クリーン、アプリパス取得ツールは常にDebugを使用する代わりに、スキームアクションの設定を尊重します。21 ほとんどのスキームはDebugで実行・テストするため、大半のプロジェクトでは何も変わりません。ただし、スキームのアクションがReleaseに設定されている場合(プロファイリング用スキームやアーカイブに近い設定で一般的です)、指定なしのbuild_simまたはtest_simはReleaseをビルドします。CLAUDE.mdやフックがDebug成果物を前提としている場合は、ツール呼び出しで明示するか、session_set_defaults でセッションごとに一度設定してください。
長時間ビルド:Claude Codeはバックグラウンドで実行するようになりました
Claude Codeの2つのリリースにより、セッション内での長時間ビルドの扱いが変わりました。v2.1.212(2026-07-16)以降、2分を超えて実行されるMCPツール呼び出しは、セッションを使い続けられるように自動でバックグラウンドへ移行します。このしきい値は CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS で設定でき、動作自体を無効にすることもできます。20 実際のプロジェクトでは、build_sim / test_sim を使ったクリーンビルドや全テスト実行は通常2分を超えます。そのため、ビルド完了を待ってターンをブロックする代わりに、エージェントはバックグラウンドでビルドを完了させながら、ファイルを読み、次の編集を計画し続けます。付随する修正も同じくらい重要です。v2.1.206(2026-07-09)より前は、--mcp-config または .mcp.json 経由で設定したサーバーごとの request_timeout_ms が新しいセッションで無視されていました。そのため、長時間のMCP呼び出しは60秒のデフォルトでタイムアウトしていました。典型的な症状は、最初のクリーンビルドがタイムアウトし、再試行すると「自然に直る」ことでした。20 ラッパースクリプトや事前ウォームアップしたビルドでこれらの挙動を回避していた場合は、その回避策を削除できます。
iOSプロジェクトのCLAUDE.mdパターン
CLAUDE.mdは、エージェント支援型開発においてプロジェクト内で最も重要なファイルです。エージェントのオンボーディング文書であり、アーキテクチャドキュメントを読んだ新入社員と、推測で進める新入社員ほどの差があります。
私が保守しているすべてのiOSプロジェクトにはCLAUDE.mdがあります。8つのアプリで得た、有効だったパターンを紹介します。
必須セクション
すべてのiOS向けCLAUDE.mdには、次の6つのセクションが必要です。それ以外は任意です。
1. プロジェクトの基本情報
# Return - Zen Focus Timer
**Bundle ID:** `com.941apps.Return`
**Target:** iOS 26+ / macOS Tahoe / watchOS 26+ / tvOS 26+
**Architecture:** SwiftUI with @Observable pattern, companion Watch and TV apps
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
これが重要な理由: エージェントはコードを書く前に、デプロイメントターゲットを知る必要があります。iOS 17を対象にするエージェントはNavigationViewと@ObservedObjectを使います。iOS 26を対象にするエージェントはNavigationStackと@Observableを使います。Bundle IDはentitlementsやHealthKit設定に関係します。Swiftのバージョンは並行処理モデル(async/awaitかcompletion handlerか、strict concurrencyかlenientか)を決めます。
2. 目的注釈付きファイル構成
## File Structure
```
Return/
├── ReturnApp.swift # App entry, dark mode enforcement
├── ContentView.swift # Main timer view with theme backgrounds
├── TimerManager.swift # Timer state, logic, and repeat handling
├── AudioManager.swift # Sound playback with AVAudioPlayer
├── Settings.swift # Centralized settings with validation
├── SettingsSheet.swift # Settings UI
├── HealthKitManager.swift # Mindful session logging + cross-device sync
├── LiveActivityManager.swift # Lock Screen/Dynamic Island
├── Theme.swift # Theme definitions
├── ThemeManager.swift # Theme state management
├── VideoBackgroundView.swift # AVPlayer video backgrounds
├── GlassTextShape.swift # Core Text glyph paths for glass effect
├── GlassTimerText.swift # Timer text with glass material
└── Constants.swift # App constants
```
各ファイル名の後ろにあるインラインコメントは飾りではありません。書けるドキュメントの中で、最も効果が高いものです。エージェントが新機能をどこに追加するか判断するとき、この注釈があれば、プロジェクト構成を理解するために全ファイルを読むのではなく、最初の試行で正しいファイルにたどり着けます。
アンチパターン: 注釈なしでファイルだけを列挙すること。TimerManager.swiftだけでは、状態を扱うのか、UIを扱うのか、その両方なのかがエージェントには分かりません。TimerManager.swift # Timer state, logic, and repeat handlingなら、そこに属するものと属さないものが明確になります。
3. ビルドとテストのコマンド
## Build & Test
Build for iOS simulator:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
```
Run tests:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Run tvOS tests:
```bash
xcodebuild -scheme ReturnTV -destination 'platform=tvOS Simulator,name=Apple TV' test
```
**Prefer MCP tools** (`build_sim`, `test_sim`) over these raw commands.
MCP returns structured JSON with categorized errors.
エージェントはMCPを優先すべきですが、生のコマンドも含めてください。生のコマンドはフォールバック用ドキュメントとして機能し、scheme名とdestinationを明示できます。
4. 主要パターンとルール
## Key Patterns
### Observable Architecture
- ALL view models use `@Observable` (NEVER `ObservableObject`)
- ALL navigation uses `NavigationStack` (NEVER `NavigationView`)
- State management via `@Observable` classes with `@MainActor` isolation
### Settings Pattern
- Centralized `Settings.shared` singleton
- All settings bounded to valid ranges with validation
- Sound names validated against whitelist
- Thread-safe access via @MainActor
### Audio System
- `AVAudioPlayer` with `.playback` category (plays in silent mode)
- Silent audio loop for background execution
- Bell playback with completion callbacks and token-based staleness
これらのパターンにより、エージェントが一貫性のない実装を持ち込むのを防げます。明示的なパターンドキュメントがないと、エージェントはあるファイルではObservableObjectを使い、別のファイルでは@Observableを使ったり、既存のSettings.shared singletonを使わず新しい設定機構を作ったりすることがあります。
5. エージェントが絶対にしてはいけないこと
## Rules
- **NEVER modify .pbxproj files** — create Swift files, then I will add them to Xcode manually
- **NEVER modify .xcodeproj/ contents directly**
- **NEVER add new package dependencies** without asking first
- **NEVER change the deployment target**
- **NEVER modify entitlements files** unless explicitly asked
- **NEVER use NavigationView** — always NavigationStack
- **NEVER use ObservableObject** — always @Observable
- **NEVER use @StateObject** — always @State with @Observable
明示的な禁止事項は、暗黙の期待よりも効果的です。エージェントは肯定的な提案よりも否定的な制約のほうが安定して守ります。禁止事項は二値的(やる / やらない)であり、ヒューリスティック(これを優先する / 場合によってはあれを使う)ではないためです。
6. フレームワーク固有のコンテキスト
このセクションはアプリによって変わります。分かりにくい設定があるフレームワークでは含めてください。
HealthKitアプリの場合:
## HealthKit Configuration
- Entitlement: `com.apple.developer.healthkit`
- Info.plist keys:
- `NSHealthShareUsageDescription`: "Return reads your mindful minutes..."
- `NSHealthUpdateUsageDescription`: "Return logs meditation sessions..."
- Category types: `HKCategoryType(.mindfulSession)`
- Authorization checked on every write (user can revoke at any time)
- HealthKit is unavailable on tvOS — guard with `#if canImport(HealthKit)`
SwiftDataアプリの場合:
## SwiftData Models
### Model Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList`
- `GroceryItem` has optional `Category`
### Model Container Setup
- Configured in App struct with `modelContainer(for:)`
- Schema versioning: currently V2
- Migration plan: `GroceryMigrationPlan` handles V1 → V2
### Queries
- `@Query(sort: \GroceryItem.name)` for sorted fetches
- `@Query(filter: #Predicate { !$0.isCompleted })` for active items
- Always use `@Query` in views, `modelContext.fetch()` in managers
SpriteKitアプリの場合:
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (SKNode, zPosition: -100)
│ └── StarfieldNode (custom, parallax scrolling)
├── gameLayer (SKNode, zPosition: 0)
│ ├── playerShip (PlayerNode, zPosition: 10)
│ ├── enemyContainer (SKNode, zPosition: 5)
│ └── bulletPool (SKNode, zPosition: 8)
├── effectsLayer (SKNode, zPosition: 50)
│ └── ParticleManager (manages explosion/trail emitters)
└── hudLayer (SKNode, zPosition: 100)
├── scoreLabel (SKLabelNode)
└── healthBar (HealthBarNode)
```
- Physics categories defined in `PhysicsCategory.swift` as bitmasks
- Contact detection via `didBegin(_ contact:)` on GameScene
- Bullet pooling: pre-allocate 50, recycle via `removeFromParent()` + re-add
Metalアプリの場合:
## Metal Pipeline
- Render pipeline: `MetalView` → `Renderer` → `ShaderLibrary`
- Compute pipeline: `AudioAnalyzer` → compute shader → texture output
- Shared uniforms struct: `Uniforms` in `ShaderTypes.h` (bridged to Swift)
- Frame timing: `CADisplayLink` drives render loop
- Buffer triple-buffering: 3 in-flight frames with semaphore
### Shader Files
- `Shaders.metal` — Main render shaders (vertex + fragment)
- `Compute.metal` — Audio analysis compute kernel
- `PostProcess.metal` — Bloom and color grading
### DO NOT modify Metal shaders without testing on device.
Simulator Metal is not representative of device GPU behavior.
実際のCLAUDE.md: Banana List(SwiftUI + SwiftData + iCloud + MCP Server)
6つのセクションがどのように連携するかを示す、注釈付きの例です。これはBanana Listで使っているCLAUDE.mdパターンです。Banana Listは、iCloud syncと、アプリのデータをClaude Desktopへ公開するカスタムMCP serverを備えた、53ファイル構成の買い物リストアプリです。
# Banana List - Grocery List App
**Bundle ID:** `com.941apps.BananaList`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData + iCloud Drive sync
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
## Core Features
- Grocery lists with items, categories, and quantities
- iCloud Drive sync via SwiftData CloudKit integration
- Custom MCP server exposing list data to Claude Desktop
- Liquid Glass design system
- Haptic feedback on interactions
- Share sheets for list sharing
## File Structure
```
BananaList/
├── BananaListApp.swift # App entry, model container setup
├── Models/
│ ├── GroceryList.swift # @Model: list with name, items, color
│ ├── GroceryItem.swift # @Model: item with name, quantity, category, isCompleted
│ ├── Category.swift # @Model: user-defined categories
│ └── SampleData.swift # Preview and test data
├── Views/
│ ├── ListsView.swift # Main list of grocery lists
│ ├── ListDetailView.swift # Items within a list
│ ├── ItemRow.swift # Single item row with swipe actions
│ ├── AddItemSheet.swift # New item form
│ ├── CategoryPicker.swift # Category selection with create-new
│ └── SettingsView.swift # App settings
├── Managers/
│ ├── CloudSyncManager.swift # iCloud Drive sync status and conflict resolution
│ └── HapticManager.swift # UIImpactFeedbackGenerator wrapper
├── MCP/
│ ├── MCPServer.swift # MCP server for Claude Desktop integration
│ ├── ListTools.swift # MCP tools: list CRUD operations
│ └── ItemTools.swift # MCP tools: item CRUD operations
└── Extensions/
├── Color+Extensions.swift # Custom color definitions
└── View+Extensions.swift # Reusable view modifiers
```
## SwiftData Models
### Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList` (required)
- `GroceryItem` has optional `Category`
- `Category` has many `GroceryItem` (nullify on delete)
### Container Setup
```swift
@main
struct BananaListApp: App {
var body: some Scene {
WindowGroup {
ListsView()
}
.modelContainer(for: [GroceryList.self, GroceryItem.self, Category.self])
}
}
```
### Query Patterns
- Lists: `@Query(sort: \GroceryList.name) var lists: [GroceryList]`
- Active items: `@Query(filter: #Predicate { !$0.isCompleted })`
- By category: filter in-memory after fetch (SwiftData predicate limitations)
## Build & Test
```bash
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Prefer MCP tools (`build_sim`, `test_sim`) over raw commands.
## Key Patterns
### Observable + SwiftData
- SwiftData `@Model` classes are automatically Observable
- DO NOT add `@Observable` to `@Model` classes (redundant, causes warnings)
- Use `@Bindable` for two-way bindings to model properties in forms
- Use `@Query` in views, `modelContext.fetch()` in non-view code
### iCloud Sync
- Automatic via SwiftData CloudKit integration
- Conflict resolution: last-write-wins (CloudKit default)
- Sync status exposed via `CloudSyncManager.shared.syncState`
- Test sync by running on two simulators with same iCloud account
### MCP Server Architecture
- Runs as a local WebSocket server on port 8765
- Exposes 6 tools: listAll, getList, createList, addItem, completeItem, deleteItem
- Claude Desktop connects via MCP config in `~/.config/claude-desktop/config.json`
## Rules
- NEVER modify .pbxproj or .xcodeproj contents
- NEVER change the model schema without updating SampleData.swift
- NEVER use `ObservableObject` — SwiftData models are already Observable
- NEVER use `@StateObject` — use `@State` with `@Observable` classes
- NEVER use `NavigationView` — always `NavigationStack`
- NEVER add `@Observable` macro to `@Model` classes
- ALWAYS use `@Bindable` for form bindings to model properties
- ALWAYS test iCloud sync changes on two simulator instances
実際のCLAUDE.md: Reps(最小構成のSwiftDataアプリ — 14ファイル)
小規模プロジェクトでは、CLAUDE.mdは簡潔で構いません。ここでは、14ファイル構成のワークアウト記録アプリRepsのパターンを示します。短いCLAUDE.mdでも、6つの必須セクションをすべて押さえている点に注目してください。
# Reps - Workout Tracking
**Bundle ID:** `com.941apps.Reps`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData
**Swift version:** 6.2
## File Structure
```
Reps/
├── RepsApp.swift # App entry, model container
├── Models/
│ ├── Workout.swift # @Model: workout with exercises, date, duration
│ ├── Exercise.swift # @Model: exercise with sets, reps, weight
│ └── ExerciseTemplate.swift # @Model: saved exercise definitions
├── Views/
│ ├── WorkoutListView.swift # Main list of workouts
│ ├── WorkoutDetailView.swift # Exercises within a workout
│ ├── ExerciseRow.swift # Single exercise with inline editing
│ ├── AddExerciseSheet.swift # Exercise selection from templates
│ ├── NewWorkoutView.swift # Start new workout flow
│ └── StatsView.swift # Progress charts and summaries
├── Managers/
│ └── WorkoutTimer.swift # Active workout timer
└── Extensions/
└── Date+Extensions.swift # Formatting helpers
```
## Build & Test
```bash
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## SwiftData Relationships
- `Workout` has many `Exercise` (cascade delete)
- `Exercise` has optional `ExerciseTemplate`
- `ExerciseTemplate` standalone (nullify on exercise delete)
## Rules
- NEVER modify .pbxproj
- NEVER use ObservableObject — use @Observable
- NEVER use NavigationView — use NavigationStack
- @Model classes are already Observable — do not add @Observable macro
- Use @Bindable for form bindings to model properties
14ファイルのプロジェクトに対して、CLAUDE.mdは40行です。書くのに10分しかかからず、エージェントの混乱を何時間分も減らせます。
実際のCLAUDE.md: Starfield Destroyer(SpriteKit + Metal — 32ファイル)
ゲームプロジェクトでは、より多くのフレームワーク固有コンテキストが必要です。エージェントはscene graph、physics category、ゲーム状態マシンを理解する必要があります。
# Starfield Destroyer - Space Shooter
**Bundle ID:** `com.941apps.StarfieldDestroyer`
**Target:** iOS 26+
**Architecture:** SpriteKit + Metal post-processing + Game Center
**Swift version:** 6.2
## Game Overview
99 levels across 3 galaxies. 8 unlockable ships with different stats.
Game Center leaderboards and achievements. Metal shader post-processing
for bloom and screen effects.
## File Structure
```
StarfieldDestroyer/
├── StarfieldDestroyerApp.swift # App entry, Game Center auth
├── GameScene.swift # Main game scene, update loop
├── MenuScene.swift # Title screen, ship selection
├── Entities/
│ ├── PlayerShip.swift # Player node with physics, weapons, shields
│ ├── EnemyShip.swift # Enemy base class with AI behaviors
│ ├── Bullet.swift # Bullet pool node
│ ├── PowerUp.swift # Collectible power-ups
│ └── Boss.swift # Boss enemies (levels 33, 66, 99)
├── Systems/
│ ├── LevelManager.swift # Level progression, wave spawning
│ ├── PhysicsCategory.swift # UInt32 bitmask categories
│ ├── CollisionHandler.swift # Contact delegate methods
│ ├── ScoreManager.swift # Score tracking, multipliers
│ ├── ParticleManager.swift # Explosion, trail, shield emitters
│ └── AudioManager.swift # Sound effects, background music
├── UI/
│ ├── HUDNode.swift # Score, health, level display
│ ├── ShipSelectView.swift # SwiftUI ship selection (UIHostingController)
│ ├── GameOverView.swift # Game over screen with score submission
│ └── PauseMenu.swift # Pause overlay
├── Metal/
│ ├── MetalRenderer.swift # Post-processing render pipeline
│ ├── BloomShader.metal # Bloom post-process effect
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Data/
│ ├── ShipData.swift # 8 ship definitions (speed, damage, shields)
│ ├── LevelData.swift # 99 level configurations
│ └── AchievementData.swift # Game Center achievement definitions
└── GameCenterManager.swift # Leaderboard/achievement submission
```
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (zPosition: -100)
│ └── StarfieldNode (parallax scrolling, 3 layers)
├── gameLayer (zPosition: 0)
│ ├── playerShip (zPosition: 10)
│ ├── enemyContainer (zPosition: 5)
│ ├── bulletPool (zPosition: 8) — pre-allocated 50 bullets
│ └── powerUpContainer (zPosition: 3)
├── effectsLayer (zPosition: 50)
│ └── ParticleManager (explosion + trail emitters)
└── hudLayer (zPosition: 100)
├── scoreLabel (SKLabelNode)
├── healthBar (custom SKShapeNode)
└── levelLabel (SKLabelNode)
```
## Physics Categories
```swift
struct PhysicsCategory {
static let none: UInt32 = 0
static let player: UInt32 = 0b1 // 1
static let enemy: UInt32 = 0b10 // 2
static let bullet: UInt32 = 0b100 // 4
static let powerUp: UInt32 = 0b1000 // 8
static let shield: UInt32 = 0b10000 // 16
static let bossBullet:UInt32 = 0b100000 // 32
}
// Contact pairs:
// player + enemy → damage
// player + powerUp → collect
// bullet + enemy → destroy
// player + bossBullet → damage
```
## Game State Machine
```
.menu → .playing → .paused → .playing
→ .gameOver → .menu
→ .bossIntro → .playing
→ .levelComplete → .playing (next level)
```
## Metal Post-Processing
- Bloom shader: `BloomShader.metal` — multi-pass Gaussian blur + additive blend
- Uniforms: `PostProcessUniforms { float intensity; float threshold; float2 resolution; }`
- Applied after SpriteKit renders each frame via `SKView.presentScene(:transition:)`
- DO NOT modify Metal shaders without testing on device
## Build & Test
```bash
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## Rules
- NEVER modify .pbxproj
- NEVER modify PhysicsCategory bitmasks (breaks all collision detection)
- NEVER change the scene hierarchy z-ordering without understanding render order
- NEVER modify ShaderTypes.h without updating both Swift and Metal references
- Add new enemies by subclassing EnemyShip, not by modifying it
- Bullet pooling: recycle via removeFromParent() + re-add, never allocate new
- Game Center: always check isAuthenticated before submitting scores
実際のCLAUDE.md: amp97(Metal + Audio Visualization — 41ファイル)
Metalプロジェクトでは、エージェントが視覚的な出力を検証できないため、最も多くのフレームワーク固有コンテキストが必要です。
# amp97 - Audio Visualizer
**Bundle ID:** `com.941apps.amp97`
**Target:** iOS 26+
**Architecture:** Metal render pipeline + AVAudioEngine analysis
**Swift version:** 6.2
## Architecture
```
Audio Input (microphone/file)
→ AVAudioEngine tap
→ FFT (vDSP)
→ Frequency/amplitude buffers
→ Metal compute shader (analysis)
→ Metal render pipeline (visualization)
→ CADisplayLink (60fps)
→ MTKView
```
## File Structure
```
amp97/
├── amp97App.swift # App entry
├── Audio/
│ ├── AudioEngine.swift # AVAudioEngine setup, tap installation
│ ├── FFTProcessor.swift # vDSP FFT, frequency bin extraction
│ ├── AudioBuffer.swift # Ring buffer for audio data
│ └── MicrophoneManager.swift # Microphone permission, session config
├── Rendering/
│ ├── MetalView.swift # MTKView wrapper for SwiftUI
│ ├── Renderer.swift # Main render loop, pipeline state
│ ├── ShaderLibrary.swift # Compiled shader management
│ ├── BufferManager.swift # Triple-buffered uniform updates
│ └── TextureManager.swift # Offscreen render targets
├── Shaders/
│ ├── Shaders.metal # Vertex + fragment shaders
│ ├── AudioCompute.metal # Audio analysis compute kernel
│ ├── PostProcess.metal # Bloom, color grading
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Visualizations/
│ ├── WaveformViz.swift # Oscilloscope-style waveform
│ ├── SpectrumViz.swift # Frequency spectrum bars
│ ├── CircularViz.swift # Radial visualization
│ └── VizSelector.swift # Visualization switching
├── Views/
│ ├── MainView.swift # Full-screen viz with overlays
│ ├── ControlsOverlay.swift # Play/pause, viz selection, gain
│ └── SettingsView.swift # Audio source, sensitivity
└── Extensions/
├── SIMD+Extensions.swift # Vector math helpers
└── Color+Metal.swift # UIColor → float4 conversion
```
## Metal Pipeline
### Uniforms (ShaderTypes.h)
```c
typedef struct {
float time;
float2 resolution;
float audioLevel; // 0.0-1.0 RMS amplitude
float frequencyBins[64]; // FFT output, normalized
float4x4 transform;
} Uniforms;
```
### Render Pipeline
1. Compute pass: AudioCompute.metal processes FFT data → texture
2. Render pass: Shaders.metal reads texture + uniforms → visualization
3. Post-process pass: PostProcess.metal applies bloom → final output
### Buffer Management
- Triple buffering with DispatchSemaphore(value: 3)
- Uniforms updated per-frame on CPU, consumed by GPU 1-2 frames later
- Audio data ring buffer: 4096 samples, lock-free single producer/consumer
## Rules
- NEVER modify ShaderTypes.h without updating BOTH Swift and Metal sides
- NEVER exceed 64 frequency bins (fixed buffer size in shader)
- NEVER test Metal visual output in simulator — device only
- NEVER modify the audio engine tap format (48kHz, mono, float32)
- Triple buffer discipline: always signal semaphore in completion handler
- Audio session: .playAndRecord category with .defaultToSpeaker option
プロジェクト規模に応じたCLAUDE.mdの調整
適切な詳細度は、ファイル数とフレームワークの複雑さによって変わります。
| プロジェクト規模 | CLAUDE.mdの深さ | 例 |
|---|---|---|
| 小規模(20ファイル未満) | 基本情報 + ファイル一覧 + ルール | Reps(14ファイル): 基本的なSwiftDataパターン、ビルドコマンド、禁止事項 |
| 中規模(20〜40ファイル) | + フレームワークコンテキスト + 主要パターン | TappyColor(30ファイル): SpriteKit scene hierarchy、physics category、game loop |
| 大規模(40ファイル以上) | + アーキテクチャ図 + 関係マップ + 複数ターゲット情報 | Return(63ファイル): クロスプラットフォームアーキテクチャ、session sync図、プラットフォームごとの差分 |
| 特化型(Metal/GPU) | + パイプライン図 + 共有型定義 + バッファレイアウト | amp97(41ファイル): render pipeline stages、uniform struct、buffer management |
ドキュメントを書きすぎるコストはほぼゼロです(エージェントは不要な部分を読み飛ばします)。一方、ドキュメント不足のコストは高くなります(エージェントがコードベースと衝突するパターンを作り出します)。
CLAUDE.mdチェックリスト
iOSプロジェクト向けCLAUDE.mdを作成または監査するときは、このチェックリストを使ってください。
- [ ] Bundle IDとデプロイメントターゲットを明記している
- [ ] Swiftバージョンとアーキテクチャパターンを明記している
- [ ] ファイル構成にインラインの目的注釈がある
- [ ] 正しいschemeとdestinationを使ったビルドコマンドがある
- [ ] 正しいschemeとdestinationを使ったテストコマンドがある
- [ ] MCPの優先方針を明記している(”prefer build_sim over xcodebuild”)
- [ ] @Observableルールがある(ObservableObjectは使わない)
- [ ] NavigationStackルールがある(NavigationViewは使わない)
- [ ] .pbxprojの禁止事項がある
- [ ] フレームワーク固有のコンテキストがある(HealthKit権限、SwiftData relationships、SpriteKit hierarchy、Metal pipeline)
- [ ] プラットフォーム可用性ガードを記載している(#if canImport、#if os)
- [ ] 主要なsingletonと共有パターンを記載している
- [ ] 既知の制限や注意点を記載している
初めてのエージェントセッション
MCP を設定し、プロジェクトに CLAUDE.md を置いたら、効果的な初回セッションの流れは次のようになります。ここでは Claude Code CLI を使いますが、このワークフローはどのランタイムにも適用できます。
ステップ 1: エージェントがプロジェクトを認識できることを確認する
You: Summarize this project. What scheme should I build with?
Claude: [reads CLAUDE.md]
[calls discover_projs via MCP]
[calls list_schemes via MCP]
This is Return, a zen meditation timer for iOS 26+, watchOS, and tvOS.
Available schemes: Return, ReturnWatch, ReturnTV, ReturnTests.
Primary scheme for iOS: Return.
エージェントが CLAUDE.md の内容に触れない場合は、ファイルがプロジェクトルート(.xcodeproj または Package.swift と同じディレクトリ)にあることを確認してください。
ステップ 2: ヘルスチェックビルドを実行する
You: Build the Return scheme for iOS simulator and report results.
Claude: [calls list_sims — finds iPhone 16 Pro on iOS 26.2]
[calls boot_sim — boots the simulator]
[calls build_sim — builds the project]
Build succeeded. 63 source files compiled.
2 warnings:
- HomeView.swift:132 — UIScreen.main deprecated in iOS 26.0
- LogWaterIntent.swift:61 — Result of try? is unused
0 errors.
ステップ 3: テストを実行する
You: Run all tests and report pass/fail.
Claude: [calls test_sim]
12 tests executed:
✓ TimerManagerTests (5/5 passed)
✓ SettingsTests (4/4 passed)
✓ ConstantsTests (3/3 passed)
All tests passed.
ステップ 4: 機能を実装する
You: Add a new "Rain" theme to the theme system. Follow the existing
pattern in Theme.swift and ThemeManager.swift. Include a rain
ambient sound. Build and test after implementation.
Claude: [reads Theme.swift — understands Theme struct pattern]
[reads ThemeManager.swift — understands theme registration]
[reads existing theme definitions]
[adds Rain theme to Theme.swift following existing pattern]
[registers Rain theme in ThemeManager.swift]
[calls build_sim — build succeeds]
[calls test_sim — all tests pass]
Added Rain theme:
- Theme.swift: new `static let rain` with video, cover, ambient
- ThemeManager.swift: added to `allThemes` array
- Build: success (0 errors, 2 existing warnings)
- Tests: 12/12 passed
Note: You'll need to add rain_ambient.wav to the project
and add the new Theme.swift changes to the Xcode target manually
(I did not modify .pbxproj).
.pbxproj を変更しないというエージェントの注記は、CLAUDE.md のルールによるものです。このルールがなければ、エージェントはプロジェクトファイルを変更しようとして、高い確率で壊してしまいます。
iOS でエージェントが得意なこと
ここでは、エージェントが最小限の人間によるレビューで、一貫して正しく本番品質の出力を出せるタスクを紹介します。
SwiftUI ビューとモディファイア
エージェントは、SwiftUI の宣言的な構文パターンを深く認識できます。ビュー構成、モディファイアチェーン、状態バインディング、レイアウトは、エージェントの学習データと相性が良い領域です。SwiftUI の API サーフェスはドキュメントが充実しており、パターンの一貫性も高いためです。
エージェントが得意な領域:
- 説明から新しいビューを作る(「X、Y、Z のトグルを持つ設定シートを作成して」)
- モディファイアチェーンを適用する(.glassEffect()、.sensoryFeedback()、.navigationTitle())
- レイアウトパターンを変換する(VStack から LazyVGrid、List から ScrollView など)
- SwiftData モデルへの @Bindable フォームバインディングを実装する
- サンプルデータ付きのプレビュープロバイダーを作る
優れた結果を生むプロンプト例:
Create a SettingsView that matches the existing pattern in SettingsSheet.swift.
Include toggles for:
- Enable haptic feedback (Settings.shared.hapticsEnabled)
- Enable HealthKit logging (Settings.shared.healthKitEnabled)
- Show session history (navigation link to SessionHistoryView)
Use Liquid Glass styling with .glassEffect() on section backgrounds.
Follow the @Observable pattern, not ObservableObject.
具体性が重要です。「設定ビューを作成して」では汎用的な出力になります。「SettingsSheet.swift の既存パターンに合わせて SettingsView を作成して」と指定すると、コードベースと一貫した出力になります。
SwiftData モデルとクエリ
エージェントは、SwiftData の @Model マクロ、リレーション、@Query パターンを安定して扱えます。このフレームワークの宣言的な性質(Django ORM や SQLAlchemy に近いもの)は、多くのコードベースでエージェントが見てきたパターンとよく対応します。
エージェントが得意な領域:
- リレーションを持つ @Model クラスを定義する
- ソート記述子と述語を使って @Query を書く
- modelContext 経由で CRUD 操作を実装する
- スキーマバージョン間のマイグレーション計画を作る
- プレビューデータとテストフィクスチャを作る
エージェントにガイダンスが必要な領域:
- 複雑な #Predicate 式(SwiftData の述語 DSL には制限があり、エージェントが常に把握しているとは限りません。既知の制限は CLAUDE.md に記載してください)
- CloudKit 同期設定(SwiftData 経由で自動化されますが、エージェントが手動同期を実装しようとする場合があります)
ユニットテスト
エージェントが書くユニットテストは、iOS プロジェクトで一貫して高品質です。エージェントは XCTest のパターン、async テストメソッド、setUp/tearDown のライフサイクルを理解しています。
Write unit tests for TimerManager covering:
1. Initial state is .stopped
2. start() transitions to .running
3. pause() transitions to .paused
4. reset() returns to .stopped with original duration
5. Timer counts down correctly (test with 3-second duration)
エージェントは、setUp() と tearDown()、適切なアサーション、タイマーベースのテストに対する async 処理を備えた、よく構造化された XCTest ケースを生成します。
リファクタリングとパターン適用
エージェントは機械的なリファクタリングを得意としています。ビューをコンポーネントに抽出する、ObservableObject を @Observable に変換する、NavigationView から NavigationStack に移行する、複数ファイルに一貫したパターンを適用する、といった作業です。
Refactor all views in the Views/ directory to use @Observable instead of
ObservableObject. Update @StateObject to @State, @ObservedObject to direct
property access, and @Published to plain properties.
エージェントは各ファイルを順に処理し、変換を正しく適用し、既存の機能を維持します。これはレバレッジの高い作業です。手作業なら 1 時間かかるリファクタリングが、ほぼ完璧な精度で数分で完了します。
MCP によるビルドエラー診断
構造化された MCP 出力があれば、エージェントはほとんどの開発者より速くビルドエラーを診断できます。エージェントはエラーの JSON を読み、正確なファイルと行を特定し、エラーメッセージを理解して修正します。多くの場合、1 ターンで完了します。
エージェントが自律的に修正できるエラー: - 不足している imports - 型の不一致 - プロトコル準拠の不足 - 非推奨の API 使用(置き換えを含む) - 必須イニシャライザーパラメータの不足 - アクセス制御違反
エージェントに支援が必要なエラー: - あいまいな型解決(複数のモジュールが同じ型を定義している場合) - 複雑なジェネリック制約の失敗 - マクロ展開エラー(エージェントは展開後のマクロ出力を確認できません)
シミュレーター管理
エージェントは MCP 経由でシミュレーターのライフサイクルをうまく扱えます。
Boot an iPhone 16 Pro simulator on iOS 26, install the app, and take a screenshot.
エージェントは list_sims を呼び出して利用可能なランタイムを探し、boot_sim でシミュレーターを起動し、build_sim でビルドとインストールを行い、screenshot でキャプチャします。すべて構造化された MCP 呼び出しを通じて実行します。
iOSでエージェントが苦手なこと
エージェントがどこで失敗するのかを正直に整理します。この境界を知っておくと、フラストレーションや無駄なトークン消費を防げます。
.pbxprojファイルの変更 — 絶対にしない
これはiOSエージェント開発で最も重要なルールです。.pbxprojファイルはXcodeのプロジェクト設定です。UUID参照、ビルドフェーズの一覧、ターゲットメンバーシップを含む構造化テキストファイルです。名目上は人間が読めますが、AIエージェントにとっては実質的に解析不能です。
エージェントが.pbxprojで失敗する理由: - ファイルは独自形式(JSONでもYAMLでもXMLでもありません)を使っており、位置に意味があります - すべてのエントリがUUIDで相互参照されています。ファイルを追加するには、3〜5個の異なるセクションを一貫して更新する必要があります - 1文字でも場所を誤ると、プロジェクトファイル全体が壊れます - Xcodeの.pbxprojマージコンフリクト解決はもともと脆弱です。エージェントによる編集はそれをさらに悪化させます
エージェントが.pbxprojを編集すると起きること: 1. 編集は成功したように見えます(エージェントは「file updated」と報告します) 2. Xcodeがプロジェクトを開けなくなります(「The project file is corrupted」) 3. git履歴から復旧するのに15〜60分かかります 4. PreToolUseフックを追加する必要性を学びます(フックを参照)
ワークフロー: エージェントがSwiftファイルを作成します。Xcodeプロジェクトへの追加は手動で行います(Xcodeへドラッグするか、File > Add Filesを使います)。1ファイルあたり5秒で済み、何時間もの復旧作業を防げます。
Swift Package Managerプロジェクトの場合: この制限はそれほど深刻ではありません。Package.swiftは標準的なSwiftファイルなので、エージェントでも安定して編集できます。プロジェクトがSPMのみを使用している場合(.xcodeprojなし)、エージェントがプロジェクト構造全体を管理できます。
複雑なInterface Builder / Storyboard編集
プロジェクトでInterface Builder(.xibファイル)やStoryboard(.storyboardファイル)を使っている場合、エージェントはそれらを意味のある形で編集できません。これらは自動生成UUID、制約参照、アウトレット接続を含むXMLファイルであり、テキスト編集ではなくビジュアル編集を前提に設計されています。
対策: 新しいビューにはSwiftUIだけを使います。プロジェクトにレガシーなInterface Builderファイルがある場合は触らず、新しいUIはSwiftUIで構築しましょう。
パフォーマンス最適化
エージェントは正しいコードを書けますが、必ずしも高性能なコードを書けるわけではありません。アプリをプロファイルしたり、ボトルネックを特定したり、フレームレートを測定したりすることはできません。パフォーマンス最適化には次が必要です。
- Instrumentsによるプロファイリング(視覚的なツールであり、エージェントからはアクセスできません)
- 特定デバイスのGPU/CPU特性の理解
- 測定に基づく反復的な変更
この問題が現れる場所: - Metalシェーダー最適化(エージェントは有効なMetalを書けますが、GPUフレーム時間は測定できません) - SwiftUIのview bodyの複雑さ(エージェントが深くネストしたビューを作成し、再描画オーバーヘッドを引き起こすことがあります) - Core Data / SwiftDataのフェッチ最適化(エージェントは正しいクエリを書けますが、大規模データセットでは遅い場合があります)
対策: 実装にはエージェントを使い、Instrumentsで手動プロファイリングします。そのうえで、特定した最適化をエージェントに適用させます。
コード署名とプロビジョニング
エージェントは、エラーメッセージを読む以上のコード署名問題のデバッグはできません。プロビジョニングプロファイル管理、証明書作成、エンタイトルメント設定、App Store提出は、Apple Developer portal、Keychain Access、Xcodeの署名UIを使う、人間が行うワークフローです。
エージェントに見えるもの: “Signing for ‘Return’ requires a development team.”
エージェントに見えないもの: 証明書が期限切れかどうか、プロビジョニングプロファイルにデバイスが含まれているか、bundle IDがApp IDと一致しているか、エンタイトルメントファイルが正しいかどうかです。
対策: 署名はすべてXcodeのSigning & Capabilitiesタブで処理します。署名失敗のデバッグをエージェントに依頼しないでください。
複雑なMetalシェーダーのデバッグ
エージェントは構文的に正しいMetal Shading Language(MSL)を書けますが、視覚出力の検証やGPU側の問題のデバッグはできません。MetalシェーダーはGPU上で実行されます。シェーダーが正しい視覚結果を生成しているかどうかについて、エージェントにはフィードバック手段がありません。
エージェントがMetalでできること:
- 説明に基づいてvertexシェーダーとfragmentシェーダーを書く
- SwiftでMetalレンダーパイプラインを設定する
- データ並列処理用のcomputeシェーダーを作成する
- .metalファイルのコンパイルエラーを修正する
エージェントがMetalでできないこと: - シェーダー出力の視覚的な正しさを検証する - GPUパフォーマンスをデバッグする(フレーム時間、occupancy、メモリ帯域幅) - 視覚的なアーティファクトを診断する(バンディング、精度の問題、誤った色空間) - 異なるGPUアーキテクチャでテストする(A-seriesとM-seriesの挙動差)
対策: Metalシェーダーは実機でテストします。SimulatorのMetal実装は、デバイスのGPU挙動を代表するものではありません。視覚デバッグにはXcodeのGPU Frame Captureを使います。
ビジュアルレイアウト検証
エージェントにはアプリのUIが見えません。SwiftUIレイアウトコードを書き、コンパイルできることは検証できますが、結果の画面が正しく見えるかどうかは判断できません。10ピクセル中心からずれているビュー、誤ったフォントウェイト、要素の重なりは、ビルドエラーを出さず、すべてのロジックテストにも合格します。
対策: UI変更は目視でレビューします。XcodeのSwiftUI Previews(またはヘッドレスレンダリング用のApple MCP経由のRenderPreview)を使ってレイアウトを検証します。自動のビジュアル回帰検出には、swift-snapshot-testingのようなライブラリを使ったスナップショットテストも検討してください。
iOS 開発向けの Hooks
Hooks は、エージェントのワークフローにおける特定のタイミングで確実に実行されるシェルコマンドです。ルールを強制する仕組みであり、「.pbxproj を編集しないでください」(エージェントが無視する可能性のある提案)と「.pbxproj は編集できません」(強制的なブロック)の違いを生みます。
hook システムの背景については、Claude Code hooks ガイドをご覧ください。このセクションでは、iOS 固有の hook パターンを取り上げます。
PreToolUse:.pbxproj への書き込みをブロックする
あらゆる iOS プロジェクトで最も重要な hook です。エージェントによる .pbxproj ファイル、.xcodeproj/ ディレクトリ、およびその他の Xcode 管理ファイルへの書き込みをブロックします。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files. Create Swift files and add to Xcode manually.\" >&2; exit 2; fi'"
}
]
}
}
プロジェクト単位で保護する場合はプロジェクトルートの .claude/settings.json に、すべてのプロジェクトを保護する場合は ~/.claude/settings.json に配置してください。
仕組み: エージェントがパターンに一致するファイルに対して Edit または Write ツールを使用しようとすると、hook が実行されます。ファイルパスを検出して stderr に警告を出力し、終了コード 2 で終了することで、ツールの使用をブロックします。エージェントはエラーメッセージを受け取り、別の方法に切り替えます。
検出対象:
- .pbxproj の直接編集
- .xcodeproj/ または .xcworkspace/ ディレクトリ内のすべてのファイル
- Interface Builder ファイル(.xib、.storyboard)
PostToolUse:SwiftFormat による保存時の自動フォーマット
エージェントが Swift ファイルを書き込みまたは編集するたびに、自動でフォーマットします。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
要件: SwiftFormat がインストールされている必要があります(brew install swiftformat)。
重要な理由: エージェントは構文的に正しい Swift を生成できますが、フォーマット規則を常に一貫して守るとは限りません。SwiftFormat はインデント、波括弧の配置、import の順序を統一します。8 保存時にフォーマットする hook を設定すれば、エージェントが触れたすべての Swift ファイルが、確認する前に自動で整形されます。
任意:プロジェクトルートに .swiftformat 設定ファイルを追加すると、フォーマット規則をカスタマイズできます。
# .swiftformat
--indent 4
--allman false
--stripunusedargs closure-only
--importgrouping testable-bottom
--header strip
PostToolUse:SwiftLint を自動実行する
SwiftLint を使用している場合は、Swift ファイルを編集するたびに実行します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftlint lint --path \"$FP\" --quiet 2>/dev/null || true; fi'"
}
]
}
}
|| true により、lint の警告でエージェントの処理がブロックされるのを防げます。lint 違反をブロックしたい場合は削除してください。
PostToolUse:変更後に自動ビルドする
フィードバックをすぐに得られるよう、Swift ファイルを変更するたびにビルドを実行します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then xcodebuild -scheme Return -destination \"platform=iOS Simulator,name=iPhone 16 Pro\" build 2>&1 | tail -5; fi'"
}
]
}
}
警告: この設定はコストがかかります。ファイルを編集するたびにビルドが実行されるため、使用は必要な場合に限りましょう。特に、ビルド結果を即座に確認したいデバッグセッションで役立ちます。通常の開発では、準備が整った段階でエージェントに MCP 経由で手動ビルドを実行させてください。
PreToolUse:Entitlements の変更をブロックする
エージェントによる意図しない変更から entitlements ファイルを保護します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.entitlements$\"; then echo \"BLOCKED: Do not modify entitlements files without explicit permission.\" >&2; exit 2; fi'"
}
]
}
}
iOS 向け Hook の統合設定
すべての iOS プロジェクトで使用している .claude/settings.json の完全な設定は次のとおりです。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard|entitlements)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode-managed files. Create Swift files and add manually.\" >&2; exit 2; fi'"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
この設定により、次の2点が保証されます。 1. エージェントは Xcode プロジェクトファイルを破損できません(PreToolUse によるブロック) 2. エージェントが触れたすべての Swift ファイルは自動でフォーマットされます(PostToolUse によるフォーマット)
エージェントと相性のよいアーキテクチャパターン
すべての Swift アーキテクチャが、同じようにエージェントと相性がよいわけではありません。次のパターンは明示的で一貫性があり、学習データにも十分含まれているため、最良の結果を得られます。
@Observable(ObservableObject は使用しない)
iOS 26以降をターゲットとする場合は、@Observable のみを使用してください。これは現代的であると同時に、エージェントとも相性のよいパターンです。
// CORRECT — @Observable
@Observable
@MainActor
final class TimerManager {
var timeRemaining: TimeInterval = 0
var state: TimerState = .stopped
func start() {
state = .running
// ...
}
}
// In a view:
struct TimerView: View {
@State private var timer = TimerManager()
var body: some View {
Text(timer.timeRemaining, format: .number)
}
}
// WRONG — ObservableObject (deprecated pattern)
class TimerManager: ObservableObject {
@Published var timeRemaining: TimeInterval = 0
@Published var state: TimerState = .stopped
}
// WRONG — @StateObject (deprecated pattern)
struct TimerView: View {
@StateObject private var timer = TimerManager()
}
@Observable がエージェントと相性のよい理由: パターンがよりシンプルで(@Published アノテーションが不要)、所有権モデルも明確です(@StateObject と @ObservedObject の使い分けではなく、@State を使用します)。構成要素が少ないため、エージェントが生成するバグも減ります。
CLAUDE.md に明記してください: iOS 26をターゲットとしていても、エージェントが学習データに含まれる ObservableObject パターンへ戻ってしまうことがあります。明示的に禁止することで防止できます。
NavigationStack(NavigationView は使用しない)
// CORRECT
NavigationStack {
List(items) { item in
NavigationLink(value: item) {
ItemRow(item: item)
}
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
// WRONG
NavigationView {
List(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
ItemRow(item: item)
}
}
}
NavigationStack はiOS 16以降で利用でき、新しいコードで使用すべき唯一のナビゲーションパターンです。型安全な navigationDestination(for:) パターンにより、エージェントが誤ったナビゲーションリンクを作成するのを防げます。
永続化には SwiftData
SwiftData モデルは、エージェント支援による開発で最も扱いやすい永続化パターンです。
@Model
final class GroceryItem {
var name: String
var quantity: Int
var isCompleted: Bool
var category: Category?
var list: GroceryList?
init(name: String, quantity: Int = 1) {
self.name = name
self.quantity = quantity
self.isCompleted = false
}
}
SwiftData を扱うエージェント向けの重要なルール:
1. @Model クラスは自動的に Observable となるため、@Observable を追加しないでください
2. フォームのバインディングには @Bindable を使用します:@Bindable var item: GroceryItem
3. ビュー内のリアクティブなデータには @Query を使用します:@Query var items: [GroceryItem]
4. ビュー以外のコードでは modelContext.fetch() を使用します
5. リレーションシップの削除には、.cascade、.nullify、.deny などのルールを明示する必要があります
Swift 6.2の並行処理
新規プロジェクトでは、Swift 6.2の厳格な並行処理をターゲットにしてください。これはツールチェーンのバージョンではなく、言語モードの選択です。安定版Xcode 26.6のSwift 6.3コンパイラでも、Xcode 27ベータ版のSwift 6.4でも、これらのパターンは変更せずにビルドできます:1718
// Actor isolation for shared mutable state
@MainActor
@Observable
final class DataManager {
var items: [Item] = []
func loadItems() async throws {
let fetched = try await api.fetchItems()
items = fetched // Safe: @MainActor isolated
}
}
// Sendable conformance for cross-actor transfers
struct Item: Sendable, Identifiable {
let id: UUID
let name: String
let createdAt: Date
}
並行処理に関するエージェント向けガイダンス:
- すべてのビューモデルに @MainActor を付けます(データ競合の警告を防止できます)
- すべての非同期処理で async/await を使用します(完了ハンドラーは使用しません)
- アクター間で受け渡す値型は Sendable にします
- ビューでの非同期初期化には Task { } を使用します
- nonisolated は、パフォーマンス上の必要性を計測によって確認した場合にのみ使用します
Liquid Glass デザインシステム(iOS 26以降)
iOS 26では、Liquid Glass デザインシステムが導入されました。明確なガイダンスを与えれば、エージェントは適切に扱えます。
// Glass effect on containers
VStack {
// content
}
.glassEffect()
// Glass effect with tint
Button("Action") { }
.glassEffect(.regular.tint(.blue))
// Glass effect on navigation bars (automatic in iOS 26)
NavigationStack {
// content
}
// Navigation bar automatically uses glass material
// Custom glass shapes
RoundedRectangle(cornerRadius: 16)
.fill(.ultraThinMaterial)
.glassEffect()
CLAUDE.md に含めてください: 「セクションの背景とカードコンテナには .glassEffect() を使用します。iOS 26では、ナビゲーションバーにガラスマテリアルが自動的に適用されます。カスタムマテリアルを使ってガラス効果を手動で再現せず、システムのモディファイアを使用してください。」
フレームワーク固有のコンテキスト
Apple の各フレームワークには、エージェントを利用する際に固有の注意点があります。このセクションでは、8つのアプリで使用したフレームワークを取り上げます。
HealthKit
使用しているアプリ: Return、Water
HealthKit では、権限処理とプラットフォームガードを慎重に扱う必要があります。
// Always check availability and authorization
import HealthKit
@MainActor
@Observable
final class HealthKitManager {
private let store = HKHealthStore()
var isAuthorized = false
func requestAuthorization() async {
guard HKHealthStore.isHealthDataAvailable() else { return }
let types: Set<HKSampleType> = [
HKQuantityType(.dietaryWater),
HKCategoryType(.mindfulSession)
]
do {
try await store.requestAuthorization(toShare: types, read: types)
isAuthorized = true
} catch {
// User denied — do not retry automatically
}
}
}
HealthKit に関するエージェント向けルール:
- 必ず HKHealthStore.isHealthDataAvailable() でガードします
- 認証済みであると決めつけず、書き込みのたびに確認します
- マルチプラットフォームのコードでは #if canImport(HealthKit) を使用します(HealthKit はtvOSでは利用できません)
- HealthKit が提供する範囲を超えて、健康データをローカルに保存しないでください
- Info.plist に NSHealthShareUsageDescription と NSHealthUpdateUsageDescription の両方を含めます
SpriteKit
使用しているアプリ: TappyColor、Starfield Destroyer
SpriteKit のシーングラフモデルを扱うには、エージェントへの明確なガイダンスが必要です。
## SpriteKit Rules
- Scene hierarchy is a tree of SKNodes with zPosition ordering
- Physics bodies use category bitmasks (UInt32) for collision detection
- Node pooling: pre-allocate reusable nodes (bullets, particles)
- Never add nodes directly to the scene — use layer nodes for organization
- Update loop: `update(_ currentTime:)` runs every frame — keep it fast
- Actions: use SKAction sequences for animations, not manual property updates
- Textures: use texture atlases for performance (.atlas directories)
SpriteKit におけるエージェントの得意分野: - SKAction のシーケンスやグループの作成 - 物理ボディと接触判定の設定 - ゲームステートマシンの実装 - HUD オーバーレイの構築
SpriteKit におけるエージェントの不得意分野: - パフォーマンスが重視されるゲームループ(エージェントはフレームごとに不要な処理を追加します) - 複雑な物理シミュレーション(精度が必要な場合は、SKPhysicsBody よりカスタム物理処理が適しています) - パーティクルエフェクトの調整(視覚的な確認と反復作業が必要です)
Metal
使用しているアプリ: amp97、Water、Starfield Destroyer
Metal は、エージェントが最も苦手とするフレームワークです。GPU プログラミングモデルはCPU側のSwiftとは根本的に異なり、エージェントは視覚的な出力を検証できません。
## Metal Rules
- Shared types between Swift and Metal go in a bridging header (ShaderTypes.h)
- Triple buffer in-flight frames (semaphore with value 3)
- Test shaders on DEVICE, not simulator (Metal behavior differs)
- Compute shaders: threadgroup size must divide evenly into grid size
- Fragment shaders: output color must be in correct color space (sRGB or linear)
- DO NOT optimize shaders without Instruments GPU profiling data
Metal プロジェクトの CLAUDE.md に含める内容: - Uniforms 構造体の定義(Swift と MSL で共有) - レンダーパイプラインステートの設定パターン - バッファインデックスとそれぞれの用途 - 存在するシェーダーと、それぞれの役割 - 既知の精度問題(half と float)
Live Activities
使用しているアプリ: Return
Live Activities には固有の設定が必要ですが、一度文書化すればエージェントは適切に扱えます。
## Live Activities
- ActivityAttributes defined in `TimerActivityAttributes.swift`
- ActivityKit framework: `import ActivityKit`
- Widget extension: `ReturnWidgets/ReturnLiveActivity.swift`
- Start: `Activity<TimerActivityAttributes>.request(attributes:content:)`
- Update: `activity.update(ActivityContent(state:staleDate:))`
- End: `activity.end(ActivityContent(state:staleDate:), dismissalPolicy:)`
- Push token: register for updates via `activity.pushTokenUpdates`
Game Center
使用しているアプリ: Starfield Destroyer
## Game Center
- Authentication: `GKLocalPlayer.local.authenticateHandler`
- Leaderboards: `GKLeaderboard.submitScore(_:context:player:leaderboardIDs:completionHandler:)`
- Achievements: `GKAchievement.report(_:withCompletionHandler:)` (takes `[GKAchievement]` array)
- Always check `GKLocalPlayer.local.isAuthenticated` before submitting
- Handle authentication failure gracefully (offline play must work)
マルチプラットフォームのパターン
Return は iOS、watchOS、tvOS にまたがります。エージェントを使ったマルチプラットフォーム開発では、明示的なプラットフォーム境界のドキュメント化が必要です。
共有コードの構成
Shared/
├── MeditationSession.swift # Data model (all platforms)
├── SessionStore.swift # iCloud sync (all platforms)
└── SessionHistoryView.swift # UI (adapts per platform)
Return/ # iOS-specific
ReturnWatch Watch App/ # watchOS-specific
ReturnTV/ # tvOS-specific
エージェント向けルール:「ファイルが Shared/ にある場合、変更はすべてのプラットフォームに影響します。ファイルがプラットフォームのディレクトリにある場合、変更はそのプラットフォームに限定されます。変更する前に、必ずファイルがどのディレクトリにあるか確認してください。」
プラットフォーム可用性ガード
// HealthKit: available on iOS and watchOS, not tvOS
#if canImport(HealthKit)
import HealthKit
// HealthKit code here
#endif
// ActivityKit: available on iOS only
#if canImport(ActivityKit)
import ActivityKit
// Live Activity code here
#endif
// WatchKit: available on watchOS only
#if os(watchOS)
import WatchKit
// Watch-specific code here
#endif
エージェント向けガイダンス:「プラットフォーム固有のフレームワークを使用する場合は、必ず #if canImport() または #if os() ガードを使用してください。フレームワークがすべてのターゲットで利用できると想定しないでください。」
プラットフォーム別 UI 適応
struct SessionHistoryView: View {
@Query var sessions: [MeditationSession]
var body: some View {
List(sessions) { session in
SessionRow(session: session)
}
#if os(tvOS)
.focusable()
#endif
#if os(iOS)
.swipeActions {
Button("Delete", role: .destructive) {
// delete
}
}
#endif
}
}
高度なワークフロー
自律的なビルド・テスト・修正ループ
最も強力なパターンは、エージェントに機能仕様を渡し、ビルド・テスト・修正のサイクルを自律的に反復させることです。
Implement a countdown timer that:
1. Starts from a user-selected duration (10, 20, or 30 minutes)
2. Shows remaining time with a circular progress indicator
3. Plays a bell sound on completion
4. Logs the session to HealthKit as mindful minutes
Build after each change. Fix all errors. Run tests when the build succeeds.
Continue until all tests pass and the build is clean.
エージェントはコードを書き、MCP 経由でビルドし、構造化されたエラーを読み取り、修正してから繰り返します。人間なら 5〜10 回のビルド・エラー修正サイクルが必要な機能でも、単一の自律ループで完了します。
有効な場合: 受け入れ基準が明確に定義された機能。
機能しない場合: 要件が曖昧な機能(「見栄えをよくして」など)、パフォーマンスに敏感なコード、または視覚的な検証が必要なもの。
iOS 向けサブエージェント委任
Claude Code のサブエージェントシステムは iOS プロジェクトでも機能します。
Use a subagent to research the best approach for implementing
iCloud key-value store sync for meditation sessions across iOS,
watchOS, and tvOS. Report back with the recommended pattern.
サブエージェントは別のコンテキストウィンドウでドキュメントとコードパターンを調査し、要約を返します。メインセッションではその推奨事項を実装します。これにより、調査で主要なコンテキストを消費することを防げます。
アプリ間でのパターン適用
一貫したパターンを持つ複数の iOS アプリを管理している場合、エージェントはあるアプリのパターンを別のアプリへ適用できます。
Look at how Settings.swift works in the Return project
(centralized singleton with validation). Apply the same pattern
to create a Settings.swift for the Water project.
エージェントは元となるパターンを読み、構造を理解したうえで、対象プロジェクトに一貫した実装を作成します。
デュアルエージェントレビュー(Claude + Codex)
重要な変更には、異なるモデルファミリーの 2 つのエージェントを使用します。
- Claude Code が実装を書く
- Codex CLI が別パスでレビューする
# After Claude implements the feature:
codex "Review the changes in the last commit. Focus on Swift 6.2
concurrency correctness, SwiftData relationship integrity,
and potential retain cycles. Report issues only — no praise."
異なるモデルファミリーは、異なる種類のエラーを検出します。これは、微妙なバグが入り込みやすい Metal シェーダーや並行処理のパターンで特に有用です。
デュアルレビューでのみ検出でき、単一レビューでは見落とされる問題:
| 問題の種類 | Claude の強み | Codex の強み |
|---|---|---|
| SwiftData のリレーションシップ循環 | 中程度 | 強い(GPT-5.6 Sol) |
| @MainActor 分離の漏れ | 強い | 中程度 |
| Metal バッファアラインメント | 中程度 | 中程度 |
| リテインサイクルの検出 | 強い(Opus) | 強い(GPT-5.6 Sol) |
| API の非推奨化に関する認識 | 強い(より新しいトレーニングデータ) | 中程度 |
| 並行処理の競合状態 | 強い | 強い(異なるパターンを検出) |
デュアルレビューの目的は、より多くのバグを見つけることではなく、異なるバグを見つけることです。各モデルファミリーは、パターン認識において異なる失敗モードを持ちます。
複数アプリにまたがるバッチ操作
フレームワークまたはパターンの変更が複数のアプリに影響する場合:
# Update @Observable pattern across all projects
for project in BananaList Return Water Reps; do
cd ~/Projects/$project
claude -p "Audit all files for any remaining ObservableObject usage.
Convert to @Observable following the pattern in CLAUDE.md.
Build and test after changes." --dangerously-skip-permissions
done
注意して使用してください。 非対話モードには --dangerously-skip-permissions フラグが必要ですが、すべての安全チェックをバイパスします。.pbxproj ファイルを保護するため、PreToolUse フックが設定されていることを確認してください。
Apple のオンデバイス LLM を使用するアプリ
アプリが Apple の Foundation Models フレームワークを呼び出す場合(たとえば、オフライン要約、分類、構造化出力の生成)、エージェントはプロンプト予算を把握する必要があります。iOS 26.4 では、以前の 4096 トークンという推測に代わる SystemLanguageModel の API が 2 つ追加されました。contextSize(モデルが単一の会話で受け入れる最大トークン数)と、tokenCount(for:)(async throws で、指定したプロンプトの実際のトークン消費量を返します)です。31 どちらも @backDeployed(before: iOS 26.4) であるため、#available ラダーなしで、FM をサポートするすべての OS バージョンで利用できます。
プロンプト構築コードを生成する際、エージェントが従うべきパターンは次のとおりです。
import FoundationModels
func budgetFor(prompt: String, reservedReply: Int = 256) async throws -> Int {
let model = SystemLanguageModel.default
let promptCost = try await model.tokenCount(for: prompt)
let budget = model.contextSize - promptCost - reservedReply
guard budget > 0 else { throw ContextError.promptTooLong }
return budget
}
アプリが SystemLanguageModel に触れる場合は、このパターンを CLAUDE.md に追加してください。追加しないと、エージェントは古い 4096 のハードコードに戻り、より大きなコンテキストウィンドウを搭載したデバイスでプロンプトを黙って切り詰めます。tokenCount(for:) の async throws シグネチャは重要です。同期バージョンを貼り付けたエージェントは、コンパイルに失敗します。
実世界のケーススタディ
抽象的なアドバイスを書くのは簡単です。ここでは、8つのアプリから、agent支援によるiOS開発が実際にどう機能するのかを示す具体的なシナリオを紹介します。失敗例も含めています。
ケーススタディ 1: ReturnへのTVアプリ追加(成功)
タスク: すでにiOS版とwatchOS版がある瞑想タイマーReturnに、tvOSターゲットを追加することでした。TVアプリには、Siri Remoteナビゲーション、大画面向けUI、iOSアプリとの設定同期が必要でした。
agentがうまくできたこと:
- 既存のiOS TimerManagerを読み、tvOSでは利用できないLive ActivitiesとHealthKitを省いたTVTimerManagerを作成しました
- Siri Remoteのフォーカスナビゲーション向けに、カスタムボタンスタイル(TVCapsuleButtonStyle、TVCircleButtonStyle)を作成しました
- Siri Remoteでは使いにくいホイールピッカーを、+/-ボタンに置き換えるTVStepperコンポーネントを構築しました
- App Groups(group.com.941apps.Return)経由で設定同期を実装しました
- 共有コード全体に#if os(tvOS)ガードを追加しました
- MCPでplatform=tvOS Simulator,name=Apple TVを指定し、ビルドとテストを実行しました
手動で行う必要があったこと: - XcodeでtvOSターゲットを作成する(File > New > Target > tvOS App) - 新しいターゲットをXcodeプロジェクトに追加する(.pbxprojの変更) - TVターゲット向けにApp Groupsエンタイトルメントを設定する - 既存のスキームにTVターゲットを追加する、または新しいスキームを作成する - agentが作成したすべてのSwiftファイルを、TVターゲットに手動で追加する - Siri Remoteナビゲーションを手動でテストする(agentはフォーカス挙動を評価できません)
結果: 約3時間のagent支援作業で、15個の新しいSwiftファイルと、完全に動作するTVアプリができました。私の見積もりでは、実装作業のおよそ80%をagentが担当し、Xcode UI操作が必要な部分(エンタイトルメント、ターゲット設定、機能フラグ)と、実機のApple TVでのフォーカステストを私が担当しました。このコードベースで同等の作業を1人で行う場合、過去にagentなしで出荷した類似機能を基準にすると、数日かかる作業だったはずです。
ケーススタディ 2: amp97のMetalシェーダーデバッグ(一部失敗)
タスク: オシロスコープシェーダーに、エネルギーベースの強度システムを追加することでした。ビジュアライゼーションが音声エネルギーに合わせて脈動する必要がありました。
起きたこと:
1. agentは、uEnergy uniformとHDRトーンマッピングを追加する、有効なMetalシェーダー変更を書きました
2. コードはエラーなくコンパイルされました
3. 実機では、ビジュアライゼーションが完全に白く表示されました。強度係数が10倍高すぎたのです(0.30ではなく3.5)
4. agentには白い画面が見えないため、フィードバック信号がありませんでした
5. 私が視覚的に問題を特定し、係数を下げるようagentに依頼しました
6. agentは係数を下げましたが、全体のエネルギーステートマシンが複雑すぎて、別の形でビジュアライザーを壊しました
7. 完全にrevertしました。2つのコミット(67959edとcda4830)を869d914でrevertしました
教訓: Metalシェーダーは、agent支援開発で最も難しい領域です。フィードバックループが切れているからです。agentは構文(コンパイルできること)と意味論(型が正しいこと)は検証できますが、出力(見た目が正しいこと)は検証できません。視覚的挙動を変えるシェーダー変更には、必ず実機での人間による検証が必要です。
この後CLAUDE.mdに追加したこと: 「極めて慎重な係数テストなしに、オシロスコープシェーダーのエネルギーステート変更を試みないこと。前回の試みでは係数が10倍高すぎて、ビジュアライザーが壊れた。」
ケーススタディ 3: Banana ListのSwiftDataマイグレーション(成功)
タスク: データモデルをV1からV2へマイグレーションし、GroceryItemにquantityフィールドを追加し、リレーションを持つ新しいCategoryモデルを追加することでした。
agentが行ったこと:
1. 既存のV1モデル定義を読みました
2. 新しいフィールドとリレーションを含むV2モデル定義を作成しました
3. SchemaMigrationPlanプロトコルに準拠したGroceryMigrationPlanを書きました
4. V1toV2マイグレーションステージを実装しました。デフォルトのquantity: 1とcategory: nilを追加しました
5. 新しいフィールドに対応するよう、すべてのビューを更新しました
6. プレビュー向けにSampleData.swiftを更新しました
7. MCP経由でビルドとテストを実行し、すべて合格しました
8. マイグレーション専用のユニットテストを作成しました
要点: SwiftDataマイグレーションは、Appleのドキュメントと学習データに十分含まれている、明確なプロトコルパターンに従うため、agentは成功しました。CLAUDE.mdにV1モデルが明示的に記録されていたため、agentは何からマイグレーションするのかを理解できました。
ケーススタディ 4: ReturnのiCloudセッション同期(複雑だが成功)
タスク: デバイス間の瞑想セッション記録を実装することでした。Apple TVやMacで完了したセッションを、HealthKit記録のためにiPhoneへ同期する必要がありました。
agentが生成したもの:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ tvOS │ │ Mac │ │ Watch │
│ TVTimerMgr │ │ TimerMgr │ │ WatchTimer │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────┼───────────────────┘
│
▼
┌────────────────────────┐
│ SessionStore │
│ (iCloud Key-Value) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ iPhone (on foreground)│
│ → Write to HealthKit │
└────────────────────────┘
agentは次を行いました。
1. UUID、日付、継続時間、ソースデバイス、HealthKit同期ステータスを持つMeditationSessionデータモデルを作成しました
2. iCloud同期向けにNSUbiquitousKeyValueStoreを管理するSessionStoreシングルトンを構築しました
3. マージ競合解決(UUIDベースの重複排除)を実装しました
4. プラットフォーム別の調整を含むSessionHistoryViewを追加しました(iOSではスワイプ削除、tvOSではフォーカスベース)
5. 他デバイスからのセッションに対して、iPhone側のHealthKit同期を接続しました
反復が必要だったこと: 初期実装では、iPhoneアプリがバックグラウンドで起動するケースを扱えていませんでした(同期のためのフォアグラウンド通知がありません)。agentには具体的な指示が必要でした。「バックグラウンドのKV変更で同期をトリガーするために、NSUbiquitousKeyValueStore.didChangeExternallyNotificationを使う」。このヒントの後、実装は正しくなりました。
教訓: アーキテクチャが明確に説明されていれば、agentはマルチプラットフォームのアーキテクチャパターンをうまく扱えます。iCloud同期パターンは単純ではありませんが、Appleのドキュメント化されたパターンに従っており、agentはそれを理解しました。エッジケース(バックグラウンド同期)には、人間のドメイン知識が必要でした。十分に文書化されていないためです。
ケーススタディ 5: Starfield DestroyerのGame Center統合(成功)
タスク: 宇宙シューティングにGame Centerのリーダーボードと実績を追加することでした。
agentがうまくできたこと:
- アプリのエントリーポイントにGKLocalPlayer.local.authenticateHandlerを実装しました
- スコア送信と実績報告のメソッドを持つGameCenterManagerを作成しました
- すべてのGame Center操作の前に、認証状態チェックを追加しました
- オフライン時のケースを適切に扱いました(Game Centerなしでもゲームはプレイでき、再接続時に送信されます)
- 8機の機体進行システムに合わせた実績定義を作成しました
手動作業が必要だったこと: - App Store Connectでリーダーボードと実績を作成する(Webポータルであり、agentはアクセスできません) - XcodeでGame Centerエンタイトルメントを設定する - サンドボックスのGame Centerアカウントでテストする(実機での手動サインインが必要です)
エージェントを使ったプロジェクトライフサイクル
新しい iOS プロジェクトを始める
エージェント支援で新しいプロジェクトを始める場合の最適なワークフローは次のとおりです。
フェーズ 1: 人間によるセットアップ(15〜30分) 1. Xcode プロジェクトを作成します(File > New > Project) 2. 署名とCapabilitiesを設定します 3. デプロイメントターゲットと対応する実行先を設定します 4. 必要なエンタイトルメントを追加します(HealthKit、Game Center など) 5. プロジェクトの識別情報とルールを含む最初の CLAUDE.md を作成します
フェーズ 2: エージェントによる実装(数時間〜数日) 1. エージェントがデータモデルを作成します(SwiftData、Core Data、またはプレーンな構造体) 2. エージェントが、文書化されたパターンに従ってビューを構築します 3. エージェントが manager/service クラスにビジネスロジックを実装します 4. エージェントがユニットテストを書きます 5. MCP による build-test-fix ループを実行します(自律)
フェーズ 3: 人間による統合(30〜60分) 1. エージェントが作成したファイルを Xcode ターゲットに追加します 2. 署名とエンタイトルメントを確認します 3. 実機でテストします 4. ビジュアルレイアウトと UX をレビューします 5. App Store Connect に提出します
既存プロジェクトを保守する
確立済みのアプリで継続的に開発する場合は、次のようにします。
You: Here's the next feature for Return: add a "Focus Score" that
calculates from session duration and consistency. Show it on
the main timer view. Build and test.
Claude: [reads CLAUDE.md, understands patterns]
[reads TimerManager.swift, Settings.swift]
[creates FocusScore.swift — model with calculation logic]
[creates FocusScoreView.swift — display component]
[integrates into ContentView.swift]
[calls build_sim — 1 error: missing import]
[fixes import]
[calls build_sim — success]
[writes FocusScoreTests.swift]
[calls test_sim — all pass]
エージェントの有効性は、CLAUDE.md がプロジェクトの現在の状態をどれだけ正確に反映しているかに比例します。重要な新機能を追加したとき、アーキテクチャパターンを変更したとき、新しいフレームワークを導入したときは、CLAUDE.md を更新してください。
エージェントに関与させるべき場合とそうでない場合
| タスク | エージェント? | 理由 |
|---|---|---|
| 新しい SwiftUI ビュー | はい | エージェントは宣言型 UI が得意です |
| SwiftData モデルの変更 | はい | 明確に定義でき、テスト可能です |
| ユニットテスト | はい | 機械的で、パターンに基づいています |
| リファクタリング | はい | 体系的で、複数ファイルにまたがります |
| ビルドエラーの診断 | はい(MCP 経由) | 構造化されたフィードバックループです |
| 新しい Xcode ターゲット | いいえ | Xcode UI と .pbxproj の変更が必要です |
| 署名とプロビジョニング | いいえ | ポータルベースで、エージェントからアクセスできません |
| ビジュアルの仕上げ | いいえ | 人間の美的判断が必要です |
| Metal シェーダーのチューニング | いいえ | デバイスでの GPU テストが必要です |
| App Store への提出 | いいえ | ポータルと Xcode Organizer が必要です |
| パフォーマンスプロファイリング | いいえ | Instruments が必要です |
| アクセシビリティ監査 | 一部 | エージェントはラベルを追加できますが、VoiceOver の確認は人間が行います |
エージェント定義を設定する
Claude Code のエージェント定義システム(.claude/agents/)を使う場合は、iOS 専用エージェントを作成します。
---
name: ios-developer
description: iOS development agent with MCP build tools and SwiftUI expertise
tools:
- XcodeBuildMCP
- xcode
---
# iOS Developer Agent
You are an iOS development agent for apps targeting iOS 26+ with SwiftUI.
## Architecture Rules
- @Observable for all view models (NEVER ObservableObject)
- NavigationStack for all navigation (NEVER NavigationView)
- SwiftData for persistence
- Swift 6.2 strict concurrency
- @MainActor on all Observable classes
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim`
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
MCP returns structured JSON. Bash returns unstructured text.
## File Management Rules
- NEVER modify .pbxproj, .xcodeproj/, .xcworkspace/, .xib, .storyboard
- Create Swift files in the correct directory
- Report files that need manual addition to Xcode targets
## SwiftData Rules
- @Model classes are automatically Observable — do not add @Observable
- Use @Bindable for form bindings to model properties
- Use @Query in views, modelContext.fetch() elsewhere
- Document relationship delete rules
## When You Get Stuck
- Build errors: use `build_sim` via MCP for structured output
- API questions: use `DocumentationSearch` via Apple MCP
- Swift verification: use `ExecuteSnippet` via Apple MCP
- Never guess — verify with tools
Claude Code セッションでは、このエージェントを @ios-developer で参照します。
エージェント支援 iOS のテストパターン
明確なガイダンスを与えると、エージェントは優れたユニットテストを書けます。最も良い結果につながるパターンを紹介します。
テストファイルの構成
# In CLAUDE.md:
## Test Structure
Tests mirror source structure:
- `ReturnTests/TimerManagerTests.swift` tests `TimerManager.swift`
- `ReturnTests/SettingsTests.swift` tests `Settings.swift`
- `ReturnTests/ConstantsTests.swift` tests `Constants.swift`
Test naming: `test_<what>_<condition>_<expected>`
Example: `test_start_whenStopped_transitionsToRunning`
テストを依頼するプロンプト
効果的なテストプロンプト:
Write unit tests for TimerManager covering:
1. Initial state is .stopped with timeRemaining == selectedDuration
2. start() transitions state to .running
3. pause() from .running transitions to .paused
4. reset() from any state returns to .stopped with original duration
5. start() from .paused resumes (state becomes .running)
6. Edge case: reset() when already stopped is a no-op
7. Edge case: pause() when already paused is a no-op
Follow the existing test pattern in SettingsTests.swift.
Use setUp() to create a fresh TimerManager for each test.
これが機能する理由: 番号付きの受け入れ条件により、エージェントにチェックリストを渡せます。既存のテストファイルを参照することで、パターンを確立できます。setUp() の使い方を指定すると、エージェントが絡み合ったテスト状態を作るのを防げます。
効果の低いテストプロンプト:
Write tests for TimerManager.
これでは汎用的で浅いテストになり、エッジケースを見逃しやすく、プロジェクトのパターンに従わない可能性があります。
Async テストパターン
タイマー ベースや async コードをテストする場合は、次のようにします。
// Agent produces this pattern when guided correctly:
final class TimerManagerTests: XCTestCase {
var sut: TimerManager!
@MainActor
override func setUp() {
super.setUp()
sut = TimerManager()
}
@MainActor
func test_start_whenStopped_transitionsToRunning() {
// Given
XCTAssertEqual(sut.state, .stopped)
// When
sut.start()
// Then
XCTAssertEqual(sut.state, .running)
}
@MainActor
func test_timerCountsDown_afterOneSecond() async throws {
// Given
sut.selectedDuration = 10
sut.reset()
sut.start()
// When
try await Task.sleep(for: .seconds(1.1))
// Then
XCTAssertLessThanOrEqual(sut.timeRemaining, 9.0)
}
}
エージェントに再確認させるべき重要なパターン:
- @MainActor クラスをテストするテストメソッドには @MainActor を付ける
- Task.sleep や async 処理を使うテストには async throws を使う
- 時間ベースのアサーションには許容誤差を持たせる(正確に 1.0 秒ではなく、1.1 秒など)
- テスト分離のために、クリーンな setUp() / tearDown() を用意する
Snapshot Testing
ビジュアルリグレッション検出には、swift-snapshot-testing の追加を検討してください。
Add snapshot tests for the main timer view in three states:
1. Stopped (showing full duration)
2. Running (showing countdown)
3. Completed (showing 00:00 with completion state)
Use SnapshotTesting library. Create reference images on first run.
エージェントは snapshot テストを正しくセットアップできますが、参照画像をレビューすることはできません。最初のスナップショットは人間がレビューし、その後はエージェントのテストが将来の変更でビジュアルリグレッションを検出します。
iOSプロジェクトのコンテキストウィンドウ管理
1Mコンテキストウィンドウ(Opus 5)は大容量ですが、無限ではありません。iOSプロジェクトでは、コンテキスト管理について特有の考慮事項があります。
iOSファイルのトークン消費量
| ファイルの種類 | 一般的なサイズ | おおよそのトークン数 |
|---|---|---|
| SwiftUIビュー(シンプル) | 50〜100行 | 500〜1,000 |
| SwiftUIビュー(複雑) | 200〜400行 | 2,000〜4,000 |
| SwiftDataモデル | 30〜80行 | 300〜800 |
| マネージャー/サービスクラス | 100〜300行 | 1,000〜3,000 |
| Metalシェーダー(.metal) | 50〜200行 | 500〜2,000 |
| ユニットテストファイル | 50〜200行 | 500〜2,000 |
| CLAUDE.md | 100〜300行 | 1,000〜3,000 |
| MCPレスポンス(ビルド) | 状況による | 200〜2,000 |
| MCPレスポンス(テスト) | 状況による | 500〜5,000 |
50ファイルのプロジェクトの場合: すべてのファイルを読み込んでも、消費するトークンは約50,000〜100,000です。1Mウィンドウには十分収まるため、エージェントはプロジェクト全体をコンテキストに保持できます。
100ファイルを超えるプロジェクトの場合: 必要なファイルを選んで読み込む必要があります。エージェントは最初にCLAUDE.md(ファイル構成の注釈を確認するため)を読み、その後、必要に応じて特定のファイルを読み込みます。CLAUDE.mdのファイル注釈が重要なのはこのためです。すべてを読み込まなくても、適切なファイルへエージェントを導けます。
大規模プロジェクト向けの戦略
- CLAUDE.mdに詳細なファイル注釈を記載する — エージェントがファイルマップを読み、関連ファイルへ直接移動できます
- サブエージェントへ委任する — 調査や探索をサブエージェントに振り分けます(独立したコンテキストで処理し、要約を返します)
- 焦点を絞ったプロンプトを使う — 「設定を更新して」よりも「SettingsView.swiftを変更して新しいトグルを追加して」のほうが効果的です
- セッションを区切る — 長いセッションを延長せず、無関係な機能には新しいセッションを開始します
/compactを使う — Claude Codeのコンパクションコマンドで会話を要約し、コンテキストを解放します
MCPのトークン効率
MCPを採用する大きな理由の1つは、構造化されたJSONレスポンスが、生のxcodebuild出力よりはるかに少ないトークンしか消費しないことです。
| シナリオ | 生のBash出力のトークン数 | MCPのトークン数 | 削減率 |
|---|---|---|---|
| ビルド成功 | 3,000〜10,000 | 200〜500 | 85〜95% |
| ビルド失敗(エラー1件) | 3,000〜10,000 | 300〜800 | 90〜92% |
| テスト結果(20件) | 2,000〜5,000 | 500〜1,000 | 75〜80% |
| シミュレーター一覧 | 500〜2,000 | 200〜400 | 60〜80% |
一般的な開発セッションで10〜20回ビルドする場合、生のxcodebuildと比べてMCPでは30,000〜150,000トークンを節約できます。その分を、実際のコード推論に利用できます。
トラブルシューティング
「build_sim failed — scheme not found」
エージェントがスキーム名を推測しています。次のように修正します。
Use discover_projs and list_schemes to find the correct scheme name
for this project before building.
または、CLAUDE.mdにスキーム名を明示します。
## Build
Primary scheme: `Return` (iOS)
Watch scheme: `ReturnWatch` (watchOS)
TV scheme: `ReturnTV` (tvOS)
「xcrun mcpbridge — command not found」
Xcode 26.3以降が必要です。xcodebuild -versionで確認してください。Xcode 26.3以降を使用しているにもかかわらずコマンドが失敗する場合は、次を実行します。
# Ensure Xcode command line tools are selected
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# Verify
xcrun mcpbridge --help
「MCPツールがClaude Codeに表示されない」
セッションの途中で登録したMCPツールは、再起動するまで表示されない場合があります。Claude Codeを終了し、新しいセッションを開始します。
# Exit current session (Ctrl+C or /exit)
# Start fresh
claude
続いて、確認します。
You: List all available MCP tools from XcodeBuildMCP.
「エージェントがMCPではなく、Bash経由でxcodebuildを使い続ける」
エージェントがTool Searchを介してMCPツールを検出できていません。解決策は2つあります。
- CLAUDE.mdに明示的な指示を追加する(エージェントにMCPの使い方を教えるをご覧ください)
- 直接指示する: 「Bash経由のxcodebuildではなく、build_sim MCPツールを使ってください」
「ビルドは成功したのに、エージェントが失敗と報告する」
XcodeBuildMCPはxcodebuildの出力を解析します。ビルドでエラーのように見える警告(非推奨に関する警告でよくあります)が出力されると、エージェントが結果を誤って解釈する場合があります。MCPレスポンスの実際のステータスフィールドを確認してください。
「シミュレーターが起動中にハングする」
すべてのシミュレーターを終了して再起動します。
xcrun simctl shutdown all
xcrun simctl boot "iPhone 16 Pro"
または、エージェントに次のように依頼します。
Shut down all simulators, then boot a fresh iPhone 16 Pro.
「CLAUDE.mdのルールがあるのに、エージェントが.pbxprojを変更しようとした」
CLAUDE.mdのルールは提案にすぎません。強制するのはフックです。.pbxprojへの書き込みをブロックするPreToolUseフックがなければ、エージェントはいずれ変更を試みます。フックをインストールしてください。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files.\" >&2; exit 2; fi'"
}
]
}
}
ルールが伝えるのは「変更しないでください」です。フックが強制するのは「変更できません」です。
FAQ
最初に使うべきエージェントランタイムはどれですか?
XcodeBuildMCPを備えたClaude Code CLIから始めましょう。MCPとの統合が最も深く、フックシステムも最も成熟しています。さらに、1Mのコンテキストウィンドウ(Opus 5)により、iOSプロジェクト全体を作業メモリに保持できます。まずはここから始め、ワークフローが成熟したら、レビュー用のCodexと、手早いインライン編集用のXcodeネイティブエージェントを追加してください。
MCPサーバーは両方必要ですか?
ほとんどの開発者にとって、XcodeBuildMCPだけでニーズの90%(ビルド、テスト、シミュレーター、デバッグ)を満たせます。ドキュメント検索、Swift REPLによる検証、SwiftUIプレビューのレンダリングが必要なら、AppleのXcode MCPを追加してください。後から追加することもでき、2つのサーバーはそれぞれ独立しています。
エージェントは新しいXcodeプロジェクトをゼロから作成できますか?
XcodeBuildMCPには、テンプレートから新しいXcodeプロジェクトを作成するスキャフォールディングツール(scaffold_ios_project、scaffold_macos_project)が含まれています。ただし、本番アプリでは、署名、Capabilities、ターゲット設定を正しく構成するため、Xcodeでプロジェクトを作成し、その後のコード実装をすべてエージェントに任せることをおすすめします。Xcodeの新規プロジェクトウィザードに費やす5分で、エージェントが生成したプロジェクト設定に起因する何時間もの問題を防げます。
エージェントはSwift Package Managerの依存関係をどのように扱いますか?
適切に扱えます。Package.swiftは標準的なSwiftファイルなので、エージェントが確実に読み書きできます。依存関係の追加、バージョン範囲の更新、ターゲットの設定はいずれも可能です。制限があるのは、.xcodeprojベースの依存関係管理(Xcodeのパッケージ解決UI)です。これはXcodeによって管理されるため、エージェントに編集させないでください。
エージェントはApp Storeに提出できますか?
できません。App Storeへの提出には、XcodeのOrganizer、プロビジョニングプロファイル、スクリーンショット、メタデータ、App Store Connectポータルが関係します。エージェントが実用的に操作できる形では、これらのいずれにもMCPやコマンドラインツールからアクセスできません。実装、テスト、バグ修正、ドキュメント作成など、アーカイブ作成までのすべてはエージェントが処理できます。提出の最終工程は、引き続き人が操作する必要があります。
ただし、App Storeのメタデータ作成にはエージェントを活用できます。最新の変更内容に基づいて、アプリの説明、キーワード、新機能のテキストを書くよう依頼してください。これはエージェントが得意とする文章生成の作業です。
エージェントを活用したiOS開発では、シークレットとAPIキーをどのように扱えばよいですか?
シークレットは絶対にコミットしないでください。バックエンドのAPIに接続するiOSアプリでは、次のように対応します。
- 環境固有の設定には
.xcconfigファイルを使用する .xcconfigファイルを.gitignoreに追加するInfo.plistのビルド設定を介して設定値を参照する- 実際の値は含めず、必要なシークレットをCLAUDE.mdに記載する
## Configuration
API base URL and keys are in `Config.xcconfig` (not committed).
Required keys:
- `API_BASE_URL` — Backend server URL
- `API_KEY` — Authentication token
Create `Config.xcconfig` from `Config.xcconfig.template`.
エージェントはキーの存在と使用箇所を把握できますが、実際の値を目にすることはありません。
SwiftUIのアニメーションもエージェントが作成できますか?
エージェントは構文的に正しいアニメーションコードを作成できますが、結果を視覚的に検証することはできません。単純なアニメーション(.animation(.spring())、.transition(.slide)、withAnimation { })なら、正しい結果が得られます。正確なタイミング調整を伴う複雑な多段階アニメーションには、エージェントだけではできない視覚的な反復調整が必要です。
効果的: 「タイマーの状態が切り替わるときに、スプリングアニメーションを追加してください。」
効果的でない: 「タイマーのアニメーションを心地よくしてください。」(主観的であり、視覚的な調整が必要です。)
エージェントはエラー処理のパターンをどのように扱いますか?
非常に適切に扱えます。エージェントはSwiftのdo/catch、Result、async throwsパターンを理解しています。
Implement error handling for the HealthKit authorization flow:
1. Check HKHealthStore.isHealthDataAvailable() — show alert if not
2. Request authorization — handle denial gracefully
3. On write failure — retry once, then show error
4. All errors should be user-facing with localized descriptions
エージェントは、ユーザー向けの適切なメッセージを備えた構造的なエラー処理を生成します。ただし、エラーを過剰に処理すること(本来は上位へ伝播させるべき例外をキャッチするなど)があるため、catchブロックを確認してください。
アクセシビリティの実装にエージェントを利用できますか?
部分的には利用できます。アクセシビリティのラベル、ヒント、traitsは正しく追加できます。
Add accessibility labels to all interactive elements in TimerView:
- Timer display: current time remaining
- Start/Pause button: current state and action
- Reset button: "Reset timer"
- Duration picker: selected duration
エージェントには、VoiceOverのナビゲーション順序が正しいかの検証、Dynamic Typeのスケーリングテスト、色のコントラスト比の評価はできません。検証にはXcodeのAccessibility Inspectorを使用してください。
エージェントはCore Dataのマイグレーション(SwiftDataを使用していない場合)をどのように扱いますか?
エージェントはCore Dataのマイグレーションマッピングとモデルバージョンを作成できますが、Xcodeで手動操作が必要な手順(新しいモデルバージョンの作成、現在のバージョンの選択)は自動化できません。SwiftDataではなくCore Dataを引き続き使用している場合は、CLAUDE.mdにモデルのバージョン履歴を記載してください。
## Core Data Model Versions
- V1: Initial (GroceryList, GroceryItem)
- V2: Added Category model (current)
- Migration: Lightweight automatic for V1→V2
エージェントはSwiftUIプレビューをどのように扱いますか?
方法は2つあります。
1. Apple Xcode MCPのRenderPreviewツールは、プレビューをヘッドレスでレンダリングして結果を返します。エージェントは、プレビューがエラーなくコンパイルおよびレンダリングされることを検証できますが、見た目が正しいかどうかは評価できません。
2. build_simによるビルドベースの検証では、プレビュープロバイダーがコンパイルできることを確認します。プレビューが実行時にクラッシュしてもビルドは成功します。クラッシュが明らかになるのは、Xcodeがプレビューをレンダリングしようとしたときだけです。
プレビューを視覚的に検証するには、引き続きXcodeを開く必要があります。
visionOSとApple Vision Proについてはどうですか?
同じパターンが適用されます。XcodeBuildMCPはvisionOSシミュレーターをサポートしており、アーキテクチャパターン(@Observable、NavigationStack、SwiftData)も同じです。RealityKit固有のコード(3Dコンテンツ、イマーシブスペース、ハンドトラッキング)にはMetalと同じ制限があります。エージェントは正しいコードを作成できますが、空間的な出力は検証できません。
エージェントが対応しにくくなるのは、どの程度の規模のプロジェクトですか?
制約となるのはコンテキストウィンドウのサイズです。Opus 5の1Mトークンウィンドウでは、Claude Codeは約50〜70個のSwiftファイルを同時に作業メモリへ保持できます。さらに大規模なプロジェクトでは、ファイル検索と選択的な読み込みを活用し、コードベースの一部ずつを扱います。100個以上のファイルがあるプロジェクトでも問題なく作業できます。すべてをコンテキストに保持するのではなく、必要に応じてファイルを読み込むだけです。
実際の限界を左右するのは、ファイル数ではなくコードベースの一貫性です。詳細なCLAUDE.mdが用意された200ファイルのプロジェクトのほうが、ドキュメントのない30ファイルのプロジェクトよりも良い結果を得られます。
エージェントを使ってiOS開発をするにはSwiftの知識が必要ですか?
エージェントの出力をレビューし、アーキテクチャ上の判断を下せる必要があります。すべての行を自分で書く必要はありませんが、エージェントの誤った選択を見抜ける程度にはSwiftを理解しておく必要があります。特に、並行処理、メモリ管理、フレームワーク固有のパターンには注意が必要です。エージェントは既存のスキルを10倍に増幅するものであり、スキルそのものに代わるものではありません。
エージェントはSwiftファイルのマージコンフリクトをどのように扱いますか?
エージェントはSwiftソースファイルのマージコンフリクトを確実に解決できます。標準的なコンフリクトマーカー(<<<<<<<、=======、>>>>>>>)は、すべてのエージェントランタイムが正しく理解します。ただし、.pbxprojファイルのマージコンフリクトは、引き続き手動で解決する必要があります。.pbxprojのコンフリクト解決をエージェントに依頼しないでください。
iOS開発でエージェントを実行するコストはどのくらいですか?
AnthropicのMaxプラン(Opus 5、1Mコンテキスト)では、一般的なiOS開発セッションは30〜120分間実行され、200K〜800Kトークンを処理します。MCPツールの呼び出しによるオーバーヘッドはごくわずかです(構造化されたJSONレスポンスは、生のビルド出力よりもトークン効率に優れています)。コストは、ほかのコードベースでClaude Codeを実行する場合と同程度です。iOS開発は、Web開発と比べて特に高価でも安価でもありません。
UIKitプロジェクトでもエージェントを使用できますか?
はい。ただし、エージェントはSwiftUIのほうが効果的に作業できます。UIKitはボイラープレートが多く、宣言的な構造が少ないうえ、エージェントが編集できないInterface Builderファイルを扱うこともよくあります。UIKitプロジェクトでは、モデル層とビジネスロジックにエージェントを使用し、UIは手動で扱う方法を検討してください。または、ビューを段階的にSwiftUIへ移行することもできます。
エージェントはローカライズをどのように扱いますか?
エージェントは.xcstrings(Xcode String Catalog)ファイルを効果的に作成、編集できます。新しいローカライズキーの追加、翻訳の提供、言語間の一貫性維持が可能です。.xcstringsファイルの構造化されたJSON形式は、エージェントが扱いやすいものです。.stringsファイル(従来形式)にも適切に対応できます。キーと値の形式が単純なためです。
iOSにおけるエージェントのよくあるミス(および防止策)
8つのiOSプロジェクトで数千回にわたるエージェントとのやり取りを通じて確認した、繰り返し発生するエラーです。それぞれに防止策があります。
ミス1:Observableパターンを混在させる
発生すること: あるファイルでは@Observable、別のファイルではObservableObjectを使用したり、すでにObservableである@Modelクラスに@Observableを追加したりします。
防止策: CLAUDE.mdに明確なルールを記載します。
- NEVER use ObservableObject — use @Observable
- NEVER add @Observable to @Model classes (already Observable)
- NEVER use @StateObject — use @State with @Observable
- NEVER use @ObservedObject — access @Observable properties directly
ミス2:クロージャで循環参照を作る
発生すること: 特にTimer.publish、NotificationCenter、完了ハンドラーで、selfを強参照するクロージャを作成します。
防止策: CLAUDE.mdにクロージャのパターンを記載します。
## Closure Pattern
- Timer callbacks: use `[weak self]` and guard
- NotificationCenter observers: store in `Set<AnyCancellable>` and use `[weak self]`
- Completion handlers: use `[weak self]` for any closure stored beyond the call site
ミス3:@MainActorの要件を無視する
発生すること: @MainActorで分離されていない@Observableクラスを作成し、Swift 6.2の並行処理に関する警告や、メインスレッド外でUIが更新された際のランタイムクラッシュを引き起こします。
防止策:
## Concurrency Rule
ALL @Observable classes MUST be @MainActor:
```swift
@Observable
@MainActor
final class SomeManager { }
```
ミス4:デスティネーションクロージャ付きのNavigationLinkを使用する
発生すること: 型安全なNavigationLink(value:)と.navigationDestination(for:)のパターンではなく、非推奨のNavigationLink(destination:label:)を使用します。
防止策:
## Navigation Pattern
ALWAYS use value-based navigation:
```swift
NavigationLink(value: item) { ItemRow(item: item) }
.navigationDestination(for: Item.self) { ItemDetailView(item: $0) }
```
NEVER use: `NavigationLink(destination: ItemDetailView(item: item)) { }`
ミス5:シミュレーター名をハードコードする
発生すること: 使用中のシステムに存在しない可能性がある特定のシミュレーター名(「iPhone 16 Pro」など)をビルドコマンドに記述します。
防止策: これはMCPで対処できます。list_simsが利用可能なシミュレーターを検出します。CLAUDE.mdには次のように記載します。
## Simulators
Do NOT hardcode simulator names. Use `list_sims` MCP tool to discover
available devices, then `boot_sim` with the discovered device ID.
ミス6:誤ったディレクトリにファイルを作成する
発生すること: 新しいビューファイルをViews/サブディレクトリではなくプロジェクトルートに作成したり、モデルを誤ったグループに配置したりします。
防止策: CLAUDE.mdのファイル構成に関する注釈で、配置場所を明示します。さらに、次のルールも記載します。
## File Placement Rules
- Views → `AppName/Views/`
- Models → `AppName/Models/`
- Managers → `AppName/Managers/`
- Extensions → `AppName/Extensions/`
- Tests → `AppNameTests/`
ミス7:プラットフォームの利用可能条件に対応しない
発生すること: HealthKitを利用できないtvOS向けにもコンパイルされる共有コードでHealthKitを使用したり、watchOSコードでActivityKitを使用したりします。
防止策:
## Platform Guards
- HealthKit: `#if canImport(HealthKit)` (unavailable on tvOS)
- ActivityKit: `#if canImport(ActivityKit)` (iOS only)
- WatchKit: `#if os(watchOS)`
- UIKit haptics: `#if os(iOS)` (unavailable on tvOS, watchOS uses WKHaptic)
ミス8:単純な機能を過剰設計する
発生すること: 20行程度のユーティリティ関数で済む処理に、プロトコル、プロトコル拡張、具象実装、ファクトリ、依存性注入コンテナまで作成します。
防止策: シンプルさを重視する原則を記載します。
## Architecture Principle
Prefer the simplest solution that handles the requirements.
- Direct implementation over protocol abstraction (unless you have 2+ conforming types)
- Concrete types over generics (unless reuse is proven)
- Extensions on existing types over new wrapper types
率直な評価
AIエージェントを活用して8つのiOSアプリをリリースした結果をまとめると、次のようになります。
エージェントが変革したもの: 実装速度です。以前は数日かかっていた作業が、数時間で完了します。SwiftUIビュー、SwiftDataモデル、ユニットテスト、リファクタリングは、今では主にエージェントが作成し、人間がレビューする形になりました。
エージェントが変革しなかったもの: アーキテクチャ上の意思決定、ビジュアルデザイン、パフォーマンス最適化、App Storeへの提出です。これらは依然として人間が主導しています。
生産性の向上は確かですが、限界もあります。 8つのアプリ全体を通じた主観的な推定では、適切なMCPとフックを設定した、十分に文書化されたプロジェクトの場合、機能提供までの時間が3〜5倍改善しました。これは対照群との比較ではなく、同じコードベースにおいて、エージェントを活用した機能開発と、同等の作業を1人で行った場合の実時間を比較したものです。文書化されておらずフックもないプロジェクトでは、改善はおそらく1.5〜2倍にとどまります。エージェントが構築するよりも推測することに時間を使いすぎるためです。33
効果のある投資: CLAUDE.md、フック、MCPの設定に費やす時間です。セットアップに1時間かけるごとに、エージェントのミスを修正するための何時間もの作業を削減できます。設定そのものがプロダクトであり、エージェントはその実行エンジンです。
意外だったこと: MCPサーバーによって、開発の進め方が大きく変わったことです。MCPを導入する前のエージェントは、たまたまSwiftを理解している高機能なテキストエディターでした。導入後は、コードの作成、ビルド、テスト、デバッグ、反復改善まで行う開発パートナーになりました。この構造化されたフィードバックループこそが、コードを書くエージェントとコードをリリースまで導けるエージェントを分ける要素です。
過去の自分に伝えたいこと: まず最小のアプリ(Reps、14ファイル)から始め、MCPとフックを適切にセットアップし、充実したCLAUDE.mdを作成してから、そのパターンをより大規模なプロジェクトへ展開しましょう。最初から63ファイルのマルチプラットフォームアプリに取り組んではいけません。プロジェクトの規模にかかわらず、インフラへの投資は同じです。まず小規模なプロジェクトで一度構築し、その後ほかのすべてのプロジェクトへコピーしてください。
今後の展望: Xcode 26.3のネイティブなエージェント統合は終着点ではなく、始まりにすぎません。AppleがMCP対応を提供したことで、ツールチェーンはエージェントファーストの開発へと移行しています。今のうちに、整理されたCLAUDE.mdファイル、テスト可能なアーキテクチャ、自動化されたフックなど、エージェントと親和性の高いプロジェクト構成へ投資する開発者は、ツールの進化とともに、その投資効果を積み上げていけるでしょう。
クイックリファレンスカード
インストール(初回のみのセットアップ)
# XcodeBuildMCP (82 tools)
claude mcp add XcodeBuildMCP -s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Apple Xcode MCP (20 tools)
claude mcp add --transport stdio xcode -s user -- xcrun mcpbridge
# Codex MCP setup
codex mcp add xcode -- xcrun mcpbridge
# Verify
claude mcp list
CLAUDE.mdに必須のセクション
1. Project identity (bundle ID, target OS, architecture)
2. File structure with annotations
3. Build and test commands
4. Key patterns and rules
5. Prohibitions (NEVER touch .pbxproj)
6. Framework-specific context
必須のフック
{
"PreToolUse": [{ "matcher": "Edit|Write", "command": "block .pbxproj" }],
"PostToolUse": [{ "matcher": "Edit|Write", "command": "swiftformat" }]
}
アーキテクチャのルール
@Observable (not ObservableObject)
NavigationStack (not NavigationView)
@State (not @StateObject)
SwiftData @Model (not Core Data)
async/await (not completion handlers)
@MainActor (on all Observable classes)
.glassEffect() (Liquid Glass, iOS 26+)
MCPツールの優先順位
Build: build_sim (not xcodebuild via Bash)
Test: test_sim (not xcodebuild test via Bash)
Sim: list_sims/boot_sim (not xcrun simctl via Bash)
Docs: DocumentationSearch (not WebSearch)
REPL: ExecuteSnippet (not swift via Bash)
変更履歴
| 日付 | 変更内容 | 出典 |
|---|---|---|
| 2026-08-16 | Codexモデルの訂正と、Xcode 27のエージェントプラットフォームの統合。 訂正(読者向けの誤り): CodexのCLIセクションと二重レビューのマトリクスでは、Codexが「OpenAIモデル(GPT-4o、o3)を使用する」としていました。いずれもCodexモデルではありません。ラインアップはGPT-5.6 Sol / Terra / Lunaに加え、GPT-5.3 Codex Spark(テキスト専用の研究プレビュー)です。GPT-5.4 / GPT-5.4-miniは2026-08-31にCodexから廃止されます。23 Xcode 27 beta 5(27A5237l、8月10日) は全体でbeta 4に代わるものです。beta 5には本文で扱うべき2項目があります。エージェントはDigital Crown、サイドボタン、Actionボタン入力を含むwatchOSアプリを検証できるようになりました(181147968)。また、sudo xcrun mcp-server enable は「Xcodeワークスペースを開かずに実行できる」MCPサーバーをプレビューします。無人実行用の--unsafe-always-allow-all-agentsもありますが、Appleと本ガイドはいずれもデスク上での使用を勧めていません(181836944)。7月29日の更新で見落とした、より大きな訂正: 「Xcode 26.3 Native Agents」セクションでは、Xcode 27がbeta 1(6月8日)時点ですでに置き換えていたインラインアシスタントを説明していました。現在のエージェントは、スキル、MCPサーバー、ACP設定を持つプラグインを受け取ります(178289210)。シミュレータを起動してタッチを合成し(175179787)、実行状態を操作してビルド設定、entitlement、Info.plistキーを変更できます(176935844)。また、ファイルシステムアクセスのセキュリティレイヤーの下で実行されます(178289431)。セクション名を変更し、制限事項リストを26.x向けに限定して27向けの訂正を加え、マトリクスをバージョン別に再構成しました。さらに、PreToolUseの.pbxprojフックはXcode内部では適用できないという運用上の注意も追加しました。LLDBはbeta 2以降、独自のMCPサーバーlldb-mcpを提供しています(176901842)。そのため、「2つのサーバー」という整理は現在では3つです。プラットフォーム:iOS/iPadOS 26.6.1(23G82)およびmacOS 26.6.2(25G82)は8月10日にリリースされました。変更なしを確認済み:XcodeBuildMCP 2.7.0、およびXcode 26 / iOS 26のSDKアップロード必須要件。 |
22 23 |
| 2026-07-29 | プラットフォーム監視を終了:iOS、iPadOS、macOS 26.6が7月27日に正式リリースされました。 直近3行に持ち越されていた未解決項目は解消されました。iOS 26.6とiPadOS 26.6はいずれもビルド23G71、macOS 26.6は25G72としてリリースされ、tvOS 26.6(23L773)、visionOS 26.6(23O770)、watchOS 26.6(23U67)も同時に提供されました。RCでテストしていた場合に注目すべき点として、23G71はAppleが7月20日にiOS 26.6 RCとして配布したものと同じビルド番号です。つまりRCは変更なしで正式版へ昇格しており、RCで検証済みのエージェント環境を再検証する必要はありません。Xcode 27 beta 4(27A5228h、7月20日)は引き続き最新のXcode betaで、XcodeBuildMCPも2.7.0(7月23日公開)のままです。いずれも前回更新以降変更されていません。過去の変更履歴は記載時点で判明していた内容を記録しているため、そのまま残しています。 | 24 |
| 2026-07-28 | レンダリング修正:孤立していた10件の引用を再接続し、変更履歴の出典列を復元。 脚注2〜11(ガイドの元々の引用セット)は、その後の更新ループで脚注12〜22が重ねられた際に本文中のマーカーを失いました。その結果、ページ上に存在しない#fnref:Nアンカーを戻り先とする参照リスト項目が10件残っていました。現在は、それぞれが実際に裏付ける主張へ接続されています。MCP仕様はプロトコル定義へ、XcodeBuildMCPリポジトリと公式サイトはツール一覧およびCLIコマンド数へ、AppleのXcode 26.3 MCPサーバーとRudrank Riyamによる独立した確認はxcrun mcpbridgeとXPCの段落へ、Swiftjective-CはネイティブのClaude AgentとCodexプロバイダーへ、Claude Codeドキュメントはランタイムの説明へ、SWE-benchはシェルより構造化ツールを使うという議論へ、SwiftFormatは保存時フォーマットフックへ接続しました。別件として、この変更履歴のヘッダーは2列と宣言していた一方で各行には3列ありました。そのためpython-markdownは各行をヘッダー幅で切り詰め、出典セルを暗黙に削除していました。ヘッダーを3列に修正しました。レンダリング済みページ上の有効な引用数:12 → 22。 |
- |
| 2026-07-25 | Claude Opus 5がデフォルトのOpusモデルに。Claude Code MCP診断。 Claude Code v2.1.219(7月24日)では、Claude Opus 5(claude-opus-5)がデフォルトのOpusモデルになりました。コンテキストは1M、基本料金はMTokあたり$5/$25(Opus 4.8から変更なし)、fast modeは$10/$50、知識カットオフは2026年5月、effortのデフォルトはhighです。Opus 4.7はfast modeから削除されたため、/fastはOpus 5またはOpus 4.8を意味します。Opus 4.6に1Mコンテキストウィンドウを帰属していたガイド本文の6か所は、現在はOpus 5としています(ランタイム比較、比較表、コンテキスト管理セクション、ランタイム推奨、作業メモリ容量とセッションコストに関するFAQの2回答)。1Mという数値と約50ファイルの作業メモリ見積もりは変わっていません。これは機能改定ではなく、モデル名の最新化です。同リリースではMCP接続診断も追加されました。claude mcp listと/mcpは、サーバー接続失敗時にHTTPステータスとエラーテキストを報告するようになりました。先頭または末尾に見えない空白を含むMCP設定値には警告が表示され、ヘッドレスのstream-json初期化イベントには、検証によってスキップされた--mcp-configエントリを列挙するmcp_server_errorsが追加されました。知っておく価値はありますが、Verificationセクションは現状のままです。HTTPステータスの部分はリモートサーバーにのみ適用され、このガイドがインストールする2つのサーバー(npx xcodebuildmcp、xcrun mcpbridge)はいずれもstdioです。iOS環境で問題になり得るのは空白警告とmcp_server_errorsであり、通常は設定パスへ誤ってコピーされた空白です。v2.1.219にはsandbox.network.strictAllowlistも追加され、サンドボックス内コマンドについて許可リストにないホストを確認なしで拒否します。これは、すでに脚注20で追跡しているsandbox.allowAppleEventsと並ぶ項目です。オプトインであり、実際のビルドに対する検証はここでは未実施ですが、想定されるiOS上の注意点は、サンドボックス化されたSPM解決やxcodebuild -resolvePackageDependenciesがgithub.comへ接続するケースです。有効にする前にパッケージホストを許可リストへ追加してください。v2.1.220(7月25日)は「バグ修正と信頼性向上」のみです。プラットフォーム監視:変更なく、引き続き未解決です。iOS 26.6とmacOS 26.6の正式版はまだリリースされていません(RCは7月20日に配布、報道向けの目標は7月27日頃)。 |
2025 |
| 2026-07-24 | XcodeBuildMCP 2.7.0。 npm latestが2.6.2 → 2.7.0へ更新されました(2026-07-23公開)。主な変更点:UI自動化ツールがDevice Hubを通じてXcode 27シミュレータで完全に動作するようになりました。シミュレータウィンドウの起動とキーボード操作も含まれます。そのため、iOS 27 betaでエージェント主導のUI検証を行う際、Xcode 26シミュレータへ戻る必要がなくなりました。iOS 27セクションとXcodeBuildMCPセクションにもその旨を記載しています。破壊的変更: ビルド/テストツールはschemaVersion: 3の構造化結果を返します(2.6.0以降はv2)。2に固定しているバリデーターは更新が必要です。動作変更: configurationを省略した場合、ビルド/テスト/クリーン/アプリパスのツールは常にDebugを使うのではなく、スキームアクションの設定を尊重するようになりました。Build & Testセクションには運用ガイダンスを追加しています(Debug成果物を前提とする場合はconfigurationを明示するか、session_set_defaultsを使用してください)。そのほか、再利用可能な.xctestproductsテスト準備パッケージ(再ビルドなしでテストを再実行し、実行ごとに新しい.xcresultを生成)、セッション既定のextraArgs、新しいxcodebuildmcp purgeワークスペースストレージコマンド、そしてツール利用可能性を10〜17秒待機するMCPクライアントの修正(誤って失敗するヘルスチェック)が含まれます。整理:正規リポジトリはgithub.com/getsentry/XcodeBuildMCPです。npmのrepositoryフィールドはここを指し、旧cameroncooke URLは301リダイレクトされます。そのため残っていた旧URLの引用を更新しました。ツール一覧は2.7.0で変更なしを確認済みです(ドキュメントは依然として12ワークフローで82件と案内しています。2.6.2と2.7.0に対する同条件のstdio tools/listでは同一の一覧が返り、CLIも引き続き100コマンド/72正規コマンドです)。プラットフォーム監視:前行から引き続き未解決です。iOS 26.6 RC(23G71)は7月20日に配布され、iOS/macOS 26.6正式版は間もなく(7月27日頃)と見込まれています。 |
1921 |
| 2026-07-21 | Xcode 26.6正式版+Xcode 27の訂正、XcodeBuildMCP 2.6.x、Claude Codeの自動バックグラウンド化。 Xcode 26.6は2026-06-25に正式リリースされました(ビルド17F113、RCは6月8日、RC 2は6月18日)。エージェントに関係するCoding Intelligenceの変更は3つです。コーディングアシスタントプロバイダーとしてのGoogle Gemini(171990272)、任意のACP互換エージェントをIntelligenceパネルへ接続できるAgent Client Protocol対応(178294840)、そしてPreview Snapshot MCPによるバリアントレンダリング(ライト/ダーク、向き、文字サイズ)(178831772)です。Swift 6.3とiOS 26.5世代のSDKを含み、macOS Tahoe 26.2以降が必要です。また、エージェントターン中のクラッシュ2件と、エージェントが質問したときのハングを修正します。前提条件は26.6以降を推奨するよう更新しました。訂正: 下記の2026-06-08行では、Appleが検証済みの「Xcode 27」バージョンを公開していないとしていましたが、記載時点で誤りでした。Xcode 27 beta(27A5194q)はWWDC初日にAppleのリリースページに掲載されており、現在はbeta 4(27A5228h、2026-07-20)です。macOS Tahoe 26.4以降でSwift 6.4とiOS 27 SDKを提供します。iOS 27セクションでは現在これを扱っており、Coding Intelligenceのplan modeに関する既知の問題178673449、RenderPreviewグループとローカライゼーションプレビュー、「Prepare Project for Localization」における削除済みキーの報告、27.0上のASanにはXcode 26.5以降が必要な点を含めています。XcodeBuildMCPは2.5.2 → 2.6.2へ更新されました(npm latest、6月2日)。v2.6.0の「runtime UI automation」リリースには、snapshot_uiの安定した要素参照と画面ハッシュ(sinceScreenHashによるスキップ)、新しいwait_for_ui/batch/dragツール、type_textのreplaceExisting、v2スキーマ結果のnextSteps、オプトインのXCODEBUILDMCP_HEADLESS_LAUNCHが追加されています。ツール数も「8カテゴリで59」から、12ワークフローカテゴリで82件のMCPツール(CLI:100コマンド、72正規コマンド)へ訂正しました。これには、XcodeBuildMCP経由でXcode-IDE専用のMCPツールを呼び出す新しいxcode-ideプロキシも含まれます。Claude Code v2.1.212(7月16日)は、2分を超えて実行されるMCP呼び出しを自動でバックグラウンド化します(CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSで調整/無効化できます)。xcodebuildによるビルドとテストは通常この時間を超えます。v2.1.206(7月9日)は、サーバーごとのrequest_timeout_msが無視される問題を修正しました(新規セッションで長時間呼び出しが既定60秒でタイムアウトする問題)。v2.1.181(6月17日)はsandbox.allowAppleEventsを追加し、サンドボックス化されたセッションでopen/osascript実行時に発生するmacOSエラー-600を修正しました。これによりopen -a Simulatorワークフローが再び利用可能になりました。プラットフォーム監視:iOS 26.6 RC(23G71)とiOS 27 beta 4はいずれも7月20日に配布されました。iOS 26.6正式版は間近です。App Storeの年齢レーティング質問票には7月9日にソーシャルメディアに関する質問が追加され、新規提出と更新では2026年9月から回答が必要になります。 |
17181920 |
| 2026-06-08 | WWDC 2026 / iOS 27 beta。 「iOS 27 and WWDC 2026: What Your Agent Now Builds With」セクションとTL;DR注記を追加しました。iOS 27は6月8日の基調講演時点でbetaです。iOS 26は引き続き提供中のリリースであるため、このセクションでは新しいフレームワークを、エージェント開発ワークフロー(ランタイム、MCP、CLAUDE.md、フック)は変わらないまま、iOS 27 beta SDKに対してターゲットとするものとして説明しています。エージェント関連の追加項目は、検証済みの詳細解説へそれぞれ相互リンクしています。Foundation ModelsのGenerationOptions.ToolCallingModeと組み込みVisionツール(OCRTool/BarcodeReaderTool)、App IntentsのLongRunningIntent/performBackgroundTask、SyncableEntity、IndexedEntityQuery、新しいCore AIフレームワーク(Apple Silicon上で独自モデルを実行)、新しいEvaluationsフレームワーク(モデル品質向けのXCTest)、さらにSwiftDataの観察/履歴、HealthKitのワークアウトゾーン、SwiftUI iOS 27です。Xcodeのバージョンガイダンスは変更ありません。Appleは検証済みの「Xcode 27」バージョンを公開していないため、ガイドはXcode 26.5安定版を推奨し続けます。運用上の注記として、2026年6月以前のモデルはiOS 26の形を前提とするため、これらのフレームワーク名をエージェントのコンテキストに記載してください。 |
1213141516 |
| 2026-05-28 | betaチャネル+WWDC26の位置づけ。 Apple Developerは5月26日、iOS 26.6、iPadOS 26.6、macOS 26.6、tvOS 26.6、visionOS 26.6、watchOS 26.6のbetaと、Xcode 26.6 betaを発表しました。呼びかけでは、新しいbeta SDKに対してXcode 26.5でビルドおよびテストするよう明示されています。そのため、エージェントワークフローではxcode-selectを安定版Xcode 26.5(ビルド17F42)に固定し、DEVELOPER_DIRをbetaへ切り替えるのではなく、将来互換性テスト用にbeta SDKを並行してインストールすべきです。WWDC26(5月18日発表) は2026年6月8日〜12日に予定されており、Swift、SwiftUI、App Intents、Foundation Models、オンデバイスのエージェントAPIにとって次の大きな転換点となる可能性があります。本ガイドのCoding IntelligenceおよびFoundation Modelsのガイダンスは、Xcode 26.5安定版を対象としています。betaチャネルのSDKは、プロダクションのエージェントワークフローに推奨する基盤ではまだありません。Apple Developerは5月21日、2026年6月18日から有効となるオーストラリアおよびベトナム向け年齢レーティング変更も発表しました。エージェントとは直接関係しませんが、ポートフォリオのコンプライアンス上、注意喚起する価値があります。 |
27 |
| 2026-05-24 | Xcode 26.5正式版のリリース日を2026-05-11へ訂正し、Appleのリリースページに基づきビルドを17F42に固定しました。この更新でのローカル検証:xcodebuild -versionはXcode 26.5/Build version 17F42を返し、xcodebuildmcpのnpm latestは2.5.2、time.modifiedは2026-05-12T07:40:41.737Zでした。27 |
|
| 2026-05-16 | 推奨Xcodeを26.5+へ更新しました(2026-05-11リリース)。エージェントワークフローに関係する新しいCoding Intelligence機能は2つあります。コーディングアシスタントでは、応答を待たずに次のリクエストをキューへ追加できるようになり、エージェントは処理前に確認質問を行えるようになりました。どちらも、XcodeのネイティブエージェントをClaude CodeまたはCodexセッションと並行して実行する際の摩擦を減らします。27 XcodeBuildMCPの最新性確認:v2.5.2(2026-05-12)が最新で、AXe 1.7.0の同梱とログキャプチャのフィルター検証問題の修正が追加されています。v2.1.0以降のxcodebuildmcp initフローは、引き続き推奨のインストールパスです。 |
|
| 2026-04-28 | エージェントワークフロー向けの推奨Xcodeを26.4+へ更新しました(26.4.1、2026-04-16、ビルド17E202が最新の安定版で、バグ修正のみです)。エージェントが記述するテストとローカライゼーションに役立つXcode 26.4の機能(2026-03-24、ビルド17E192)を引用しました:Swift Testingの画像添付、Issue.recordの重大度、クラッシュログが添付されるUIテストのクラッシュ警告(特にXCUIApplication(bundleIdentifier:)/XCUIApplication(url:)アプリ向け)、String Catalogエディタの改善です。手動MCP設定の代替として、xcodebuildmcp init自動インストーラー(v2.1.0以降、2026-02-23)を追加しました。 |
|
| 2026-04-27 | App Store Connect:Xcode 26以降による提出が2026-04-28から必須になります。Foundation ModelsにはSystemLanguageModel.contextSizeとtokenCount(for:) APIが追加されました(iOS 26.4へバックデプロイ済み)。エージェント生成FMプロンプト予算コードのパターンを追加しました。iOS 26.4.2(4月22日)とiOS 26.5 beta 3(4月20日)は、エージェントツールチェーンに影響する変更なしでリリースされました。 |
|
| 2026-04-13 | 初回公開。8アプリ、3ランタイム、MCP設定、CLAUDE.mdパターン、フック、ケーススタディ。 |
参照
-
XcodeBuildMCP には、デフォルトで Sentry テレメトリーが含まれています。プロジェクトのプライバシー文書には、送信される内容として、エラーメッセージ、スタックトレース、場合によってはファイルパスが詳しく記載されています。
XCODEBUILDMCP_SENTRY_DISABLED=true環境変数を設定すると、完全にオプトアウトできます。 ↩ -
Anthropic、「Model Context Protocol Specification」、modelcontextprotocol.io/specification。MCP 仕様では、XcodeBuildMCP と Apple の Xcode MCP の両方が実装する JSON-RPC トランスポート、ツール検出、およびリソースプロトコルが定義されています。 ↩
-
XcodeBuildMCP、github.com/getsentry/XcodeBuildMCP。オープンソースで、Sentry が保守しています。シミュレーター、デバイス、デバッグ、UI 自動化、カバレッジ、Swift パッケージを含む 12 のワークフローカテゴリにわたって、82 のツール(v2.6.x 時点)を提供しています。変更履歴付きのセマンティックバージョニングを採用しています。 ↩
-
Apple は、Xcode 26.3 のインテリジェント開発者ツール施策の一環として Xcode MCP サーバーを導入し、MCP を AI コーディングアシスタントと Xcode ツールチェーンの間のインターフェース層として位置付けました。公式ドキュメントについては、Xcode Release Notesをご覧ください。 ↩
-
Rudrank Riyam、「Exploring Xcode Using MCP Tools」、rudrank.com/exploring-xcode-using-mcp-tools-cursor-external-clients、2026年。Apple の MCP ツール数、XPC 依存関係、ドキュメント検索機能を独自に確認しています。 ↩
-
Jimenez, C.E., Yang, J., Wettig, A., et al.、「SWE-bench: Can Language Models Resolve Real-World GitHub Issues?」ICLR 2024。arxiv.org/abs/2310.06770。構造化されたツールアクセスを持つエージェントは、非構造化シェルコマンドに限定されたエージェントを大幅に上回りました。この結果は、エージェントの有効性における構造化 MCP インターフェースの妥当性を裏付けています。 ↩
-
Claude Code CLI ドキュメント、code.claude.com。フックシステム、MCP 設定、サブエージェント委任、エージェント定義。 ↩
-
SwiftFormat、github.com/nicklockwood/SwiftFormat。一貫したコードスタイルのために PostToolUse フックで使用される Swift フォーマットツールです。 ↩
-
XcodeBuildMCP 公式サイト、xcodebuildmcp.com。ツール参照では、ワークフロー別にまとめた 82 の MCP ツールを案内しており、CLI には 12 カテゴリにわたる 100 コマンド(うち 72 が正規コマンド)が掲載されています。Homebrew または npx でインストールできます。 ↩
-
Swiftjective-C、「Agentic Coding in Xcode 26.3 with Claude Code and Codex」、swiftjectivec.com、2026年2月。Xcode 26.3 が、Settings > Intelligence を通じてネイティブの Claude Agent と Codex ランタイムサポートを提供することを確認しています。
xcrun mcpbridgeを通じて 20 の MCP ツールが公開されます。 ↩ -
Blake Crosley、「Two MCP Servers Made Claude Code an iOS Build System」、blakecrosley.com/blog/xcode-mcp-claude-code、2026年2月。同じ著者の iOS 開発ワークフローにおけるセットアップ手順と実運用での結果です。 ↩
-
Foundation Models in iOS 27: Tool-Calling Control。Apple の Foundation Models に関する iOS 27 ベータドキュメント(
GenerationOptions.ToolCallingMode、OCRTool、BarcodeReaderTool)を情報源としています。WWDC 2026、2026年6月8日に検証済みです。 ↩↩ -
App Intents in iOS 27: Background, Sync, Spotlight。Apple の App Intents に関する iOS 27 ベータドキュメント(
LongRunningIntent、performBackgroundTask(options:operation:)、SyncableEntity、IndexedEntityQuery)を情報源としています。WWDC 2026、2026年6月8日に検証済みです。 ↩↩ -
Core AI: Running Models on Apple Silicon。Apple Silicon 上で独自モデルを実行するための新しい iOS 27 / macOS 27 Core AI フレームワークを扱っています。WWDC 2026、2026年6月8日に検証済みです。 ↩↩
-
Evaluations: XCTest for Model Quality。テストスイートでモデル出力の品質を測定する、新しい macOS 27 Evaluations フレームワークを扱っています。WWDC 2026、2026年6月8日に検証済みです。 ↩↩
-
SwiftData in iOS 27: Observation and History、HealthKit in iOS 27: Workout Zones, New Types、What’s New in SwiftUI for iOS 27。いずれも Apple の iOS 27 ベータドキュメントを情報源としています。WWDC 2026、2026年6月8日に検証済みです。 ↩↩
-
Apple、“Xcode 26.6 Release Notes” および Apple Developer Releases。Xcode 26.6(ビルド 17F113)は 2026-06-25 に掲載され、RC(17F109)は 2026-06-08、RC 2(17F113)は 2026-06-18 です。リリースノートからの引用:「Google Gemini is now available in the coding assistant」(171990272)、「Xcode adds support for the Agent Client protocol」(178294840)、「The Preview Snapshot MCP tool can now render variants such as light/dark appearance, portrait/landscape orientation, and various type size overrides」(178831772)。また、アクティブなエージェントターン中にウィンドウを閉じた際のクラッシュ(174186260)、絶対パスでないパスを含むエージェントのファイル操作中のクラッシュ(174752919)、「a bug that could cause Xcode to hang indefinitely when an agent asked the user a question」(177989242)を修正しています。Xcode 26.6 には Swift 6.3 と、iOS 26.5、iPadOS 26.5、tvOS 26.5、watchOS 26.5、macOS 26.5、visionOS 26.5 向けの SDKs が含まれます。macOS Tahoe 26.2 以降が必要です。リリースノート本文は 2026-07-21 に検証しました。 ↩↩↩↩↩↩↩
-
Apple、“Xcode 27 Release Notes” および Apple Developer Releases。Xcode 27 ベータ(27A5194q)は 2026-06-08、つまり WWDC 初日に掲載され、ベータ 4(27A5228h)は 2026-07-20 に掲載されました。Xcode 27 ベータ 4 には Swift 6.4 と、iOS 27、iPadOS 27、tvOS 27、watchOS 27、macOS 27、visionOS 27 向けの SDKs が含まれます。macOS Tahoe 26.4 以降が必要です。引用項目:プランモードの確認バー(「Implement the plan?」)の既知の問題として、エージェントがまだストリーミング中にクリックすると、重複するエージェントターンが発生する可能性があります(178673449)。RenderPreview MCP ツールは新しいグループ機能を使った Preview のレンダリング(174692209)と、異なるローカリゼーションでの UI プレビュー(181040291)をサポートします。「Prepare Project for Localization」エージェントツールには、ソースに表示されなくなったため削除された String Catalog キーが表示されるようになりました(179755385)。Xcode 26.4 以前でビルドした場合、Address Sanitizer は iOS/tvOS/watchOS/visionOS 27.0 で起動に失敗することがあります。回避策は Xcode 26.5 以降です(178072780)。リリースノート本文は 2026-07-21 に検証しました。 ↩↩↩↩↩↩
-
XcodeBuildMCP v2.6.0 リリース、2026-06-01(「runtime UI automation」)。続いて v2.6.1 と v2.6.2 がリリースされ、v2.6.2 が npm の最新です(2026-07-21 に検証:
npm view xcodebuildmcp dist-tags.latest→2.6.2、公開日 2026-06-02)。ツール数は公式ドキュメント(xcodebuildmcp.com/docs/tools:「All 82 tools XcodeBuildMCP advertises, grouped by workflow」)によるもので、2026-07-21 に v2.6.2 でローカル照合しました。xcodebuildmcp toolsは、12 のワークフローカテゴリ(coverage、debugging、device、macos、project-discovery、project-scaffolding、simulator、simulator-management、swift-package、ui-automation、utilities、xcode-ide)にわたる 100 の CLI コマンド(72 が正規コマンド)を報告します。また、12 のワークフローすべてを有効にした stdio のtools/listは、このガイドのインベントリテーブルで使用しているツール名(wait_for_ui、batch、drag、xcode_ide_list_tools、xcode_ide_call_toolを含む)を返しました。約 70% の実時間、約 68% のトークン、約 76% のツール呼び出し削減という数値は、決定論的な Weather アプリタスクにおけるプロジェクト独自のベンチマークであり、独立した測定ではありません。 ↩↩↩↩↩↩ -
Claude Code CHANGELOG。v2.1.212(2026-07-16):「MCP tool calls running longer than 2 minutes now move to the background automatically so the session stays usable; configure the threshold or disable with
CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS.」v2.1.206(2026-07-09):「Fixed MCP servers configured via--mcp-configor.mcp.jsonignoring a per-serverrequest_timeout_ms, which caused long-running MCP tool calls to time out at the 60s default in fresh sessions.」v2.1.181(2026-06-17):「Addedsandbox.allowAppleEventsopt-in setting that lets sandboxed commands send Apple Events on macOS」および「Fixedopen,osascript, and browser-based auth flows failing with error -600 on macOS by adding the Apple Events entitlement.」v2.1.219(2026-07-24):「Added HTTP status and error text toclaude mcp listand/mcpwhen a server fails to connect」、「Added a warning for MCP config values with hidden leading or trailing whitespace」、「Addedmcp_server_errorsto the headless stream-json init event, listing--mcp-configentries skipped」、および「Addedsandbox.network.strictAllowlistsetting to deny non-allowlisted hosts for sandboxed commands.」v2.1.220(2026-07-25):「Bug fixes and reliability improvements」のみです。変更履歴本文は 2026-07-21 に検証し、v2.1.218-v2.1.220 のエントリは 2026-07-25 に検証しました。 ↩↩↩↩↩ -
XcodeBuildMCP v2.7.0 リリース、2026-07-23。npm の最新バージョンは 2026-07-24 に検証しました(
npm view xcodebuildmcp dist-tags.latest→2.7.0、公開日 2026-07-23T14:07Z)。リリースノートからの引用:Xcode 27 Device Hub — 「UI automation tools now work fully with Xcode 27 simulators through Device Hub, including simulator window launching and keyboard controls」。破壊的変更として、ビルドおよびテストツールはschemaVersion: 3を返すため、バージョン 2 に固定されたバリデーターに影響します。動作変更として、「Build, test, clean, and app-path commands now honor the scheme action’s configuration when configuration is omitted instead of always using Debug」。さらに、.xctestproductsの再利用可能なテスト準備パッケージ、xcodebuildmcp purgeワークスペースストレージコマンド(デフォルトでドライラン)、セッション既定のextraArgsと呼び出し単位のオーバーライド、「Fixed MCP clients waiting 10–17 seconds for tools to become available, which could make short health checks report a failed connection.」が含まれます。リポジトリのホーム:npm のrepositoryフィールドはgithub.com/getsentry/XcodeBuildMCPを指しており、github.com/cameroncooke/XcodeBuildMCPはそこへ 301 リダイレクトします(いずれも 2026-07-24 に確認)。getsentry URL を引用してください。ツール数:リリースノートに数の記載はなく、公式ドキュメント(xcodebuildmcp.com/docs/tools)は依然として「All 82 tools」を案内しています(2026-07-24 に取得)。このセッションで、同条件の stdiotools/listをxcodebuildmcp@2.6.2 mcpと@2.7.0 mcpに対して照合しました(同じ 12 ワークフローを有効化し、それぞれserverInfo.versionを確認)。両者はバイト単位で同一のツールインベントリを返しました(この環境で公開されたのは 76。案内されている 82 には環境条件付きのツールが含まれます)。また、2.7.0 のxcodebuildmcp toolsも、同じ 12 カテゴリにわたる 100 コマンド、72 の正規コマンドを報告します。したがって、12 カテゴリにまたがる 82 というインベントリは、変更なく v2.7.0 にも適用されます。 ↩↩↩↩↩↩↩ -
Apple、“Xcode 27 Release Notes”。2026-08-16 に DocC JSON から読み取りました(HTML ページはクライアントサイドでレンダリングされ、フェッチャーにはテキストを返しません)。ベータ 5(27A5237l、2026-08-10)、原文:「Coding Intelligence agents can now verify watchOS apps, including rotating and pressing the Digital Crown, and pressing the side and Action buttons (Apple Watch Ultra). (181147968)」および「Xcode 27 Beta 5 adds a preview of a new MCP server experience that runs without requiring an open Xcode workspace… You can turn this experience on by using
sudo xcrun mcp-server enable. Check its state afterward withxcrun mcp-server status… Developers running agents in unattended environments can approve all permissions upfront withsudo xcrun mcp-server enable --unsafe-always-allow-all-agents. This is not a recommended configuration for at-desk use. (181836944)」。ベータ 1(2026-06-08):skills、MCP サーバー、ACP 構成を備えたプラグイン(178289210)、ファイルシステムアクセスのセキュリティレイヤー(178289431)、シミュレーターの起動、インストール、起動実行、タッチ合成、スクリーンショット取得(175179787)、MCP デバッガー、スキーム、ビルド設定/エンタイトルメント/Info.plist ツール(176935844)、ファーストクラスのプランニング(172857081)、プロジェクトインサイト(177568662)。ベータ 2:「LLDB now ships with an MCP server (lldb-mcp)」(176901842)。ビルド番号と日付は Apple Developer Releases と照合しました。 ↩↩↩↩↩↩↩↩ -
OpenAI、Codex models(developers.openai.com/codex/models からのリダイレクト先の正規 URL)、2026-08-16 に取得。推奨モデル:「5.6 Sol — Flagship GPT-5.6 model with the strongest capability for complex coding, computer use, research, and cybersecurity」、「5.6 Terra — Balanced GPT-5.6 model for everyday work」、「5.6 Luna — Fast and affordable GPT-5.6 model」。GPT-5.3 Codex Spark はテキスト専用の研究プレビューです。同ページには、GPT-5.4 と GPT-5.4-mini は 2026年8月31日に Codex から廃止され、5.6-terra と 5.6-luna が後継になると記載されています。GPT-4o と o3 はどちらも Codex モデルとして掲載されていません。 ↩↩↩
-
Apple Developer releases feed。iOS 26.6(23G71)、iPadOS 26.6(23G71)、macOS 26.6(25G72)、tvOS 26.6(23L773)、visionOS 26.6(23O770)、watchOS 26.6(23U67)はすべて 2026年7月27日(月)付です。7月20日の iOS 26.6 RC は同じ 23G71 ビルド番号であり、RC が安定版として出荷されました。2026年7月20日(月)付の Xcode 27 ベータ 4(27A5228h)は、依然として最新の Xcode エントリです。リリース RSS フィードに対して 2026-07-29 に検証しました。 ↩
-
Anthropic、“Introducing Claude Opus 5”(2026-07-24)およびモデル概要。Claude Opus 5(
claude-opus-5):コンテキストウィンドウは 100 万トークン(デフォルトかつ最大値)、最大出力は 128K、料金は MTok あたり $5 / $25 で Opus 4.8 と同じ基本価格、fast mode は $10 / $50、信頼できる知識のカットオフは 2026年5月です。Claude API および Claude Code では、effortのデフォルトはhighです。Claude Code CHANGELOG v2.1.219(2026-07-24):「Added Claude Opus 5 (claude-opus-5), now the default Opus model — 1M context, fast mode at $10/$50 per Mtok.」。Opus 4.7 は fast mode から削除され、/fastは Opus 5 と Opus 4.8 に適用されます。2026-07-25 に検証済みです。 ↩↩ -
Apple Developer News、“Upcoming Requirements”。2026-04-28 のエントリ:「Apps uploaded to App Store Connect must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26, or watchOS 26.」この要件の対象プラットフォーム一覧に macOS は含まれていません。 ↩
-
Apple、“Xcode 26.5 Release Notes” および “Xcode 26.5 (17F42) - Releases”。Xcode 26.5 は、ビルド 17F42 として 2026-05-11 に Apple が掲載しました。リリースノートから引用した Coding Intelligence の 2 機能:現在の応答が終わるまで待たずにコーディングアシスタントでメッセージをキューに追加できること(174563016)、エージェントが進行前にコンテキストを収集するための明確化質問をできること(175182375)。さらに、12 か月コミットメントの月額サブスクリプションに対する StoreKit Testing サポート(
PricingTermsモデル、billingPlanTypePurchaseOption、TransactionとSubscriptionRenewalInfoのCommitmentInfo)と、async/await 操作中にスレッドを移行する Swift Tasks のステップ実行に関する Swift デバッガー修正も含まれます。2026-05-24 の現セッション検証:xcodebuild -versionはXcode 26.5とBuild version 17F42を返し、npm view xcodebuildmcp version dist-tags.latest time.modified --jsonは、最新2.5.2とtime.modified2026-05-12T07:40:41.737Zを返しました。併せて参照:9to5Mac、“Xcode 26.5 adds two features that make agentic coding more useful”、2026-05-12。 ↩↩↩↩ -
Apple、“Xcode 26.4 Release Notes”。Xcode 26.4(2026-03-24、ビルド 17E192)。リリースノートから引用した機能:Swift Testing は
CGImage、NSImage、UIImage、CIImageによる画像添付をサポートするようになりました。Issue.recordは重要度レベルを受け取ります。一部の UI テストアプリのクラッシュ、具体的にはXCUIApplication(bundleIdentifier:)またはXCUIApplication(url:)で操作されるアプリのクラッシュは、テスト失敗ではなく、クラッシュログ添付の警告として報告されます。String Catalog エディターにはエントリの切り取り/コピー/貼り付け、言語削除、既存言語からの翻訳の事前入力、およびBUILD_ONLY_KNOWN_LOCALIZATIONS設定が追加されています。 ↩ -
Apple Developer News、“Xcode 26.4.1 (Build 17E202) Now Available”、2026-04-16。バグ修正のみのドットリリースです。iOS / macOS / visionOS の 26.4 より前で欠落シンボルに起因する MetricKit クラッシュと、Swift の async スタック割り当てバグ(
swift_asyncLet_finishの「freed pointer was not the last allocation」)を修正しています。 ↩ -
getsentry/XcodeBuildMCP v2.1.0 リリース、2026-02-23。エージェント skills と MCP 設定を一度にインストールする
xcodebuildmcp initCLI コマンドを追加し、単独のinstall-skill.shスクリプトを置き換えました。Claude Code、Cursor、Codex を自動検出し、--print(非対応クライアント向けに設定を stdout へ出力)と--uninstall(削除)をサポートします。 ↩ -
InfoQ、“Apple Adds Context Window Management to Foundation Models”、2026年3月。新しい
SystemLanguageModel.contextSizeおよびtokenCount(for:)APIs を記録し、@backDeployed(before: iOS 26.4)アノテーションを確認しています。従来のコミュニティによる 4096 トークン固定という推測を置き換えるものです。 ↩ -
2026-04-27 に、8 つの非公開アプリリポジトリそれぞれに対して
find . -name '*.swift' -not -path '*/Tests/*' | wc -lを実行して算出したファイル数です。テストファイルは除外しています。合計は §The Portfolio のアプリ別内訳テーブルと内部的に整合しています。 ↩ -
対照群との比較測定ではなく、主観的な実時間の見積もりです。3〜5 倍という数値は、2026 年にエージェント支援で実装した機能と、エージェントワークフロー以前に同じコードベースで単独開発して出荷した同等機能の実装時間を、著者が記憶に基づいて比較したものです。MCP とフックのセットアップ後に期待できることの目安として扱い、ベンチマークとは見なさないでください。 ↩