
はじめに
こんにちは、スタメンでEMをしている あさしん(@asashin227)です。
4月12日〜14日の3日間、立川ステージガーデンで開催されたtry! Swift Tokyo 2026に参加してきました。
try! Swift Tokyoは、世界中からAppleプラットフォームの開発者が集まる国内最大級のSwiftカンファレンスです。今年は21セッション・5ワークショップの充実したプログラムが用意されました。
会場:立川ステージガーデン
昨年から会場が変更され、立川ステージガーデンでの開催となりました。渋谷や新宿といった都心と比べて街が落ち着いており、自然も多く過ごしやすい環境でした。
今年はステージ背面がオープンになり、外と繋がった構造になっていたことが印象的でした。開放感があり、外から発表をのぞき見ることもできる点が新鮮でした。また、昨年から引き続きスライド下にリアルタイム翻訳が表示されるようになっており、英語セッションでもストレスなく内容を追えるようになった点は、カンファレンス体験として大変満足度の高いものでした。
私はワークショップ(4/12)+カンファレンス2日間(4/13〜14)のフルで参加しました。

iOS Private Playgrounds ワークショップ体験記
5つのワークショップの中から、iOS Private Playgroundsを選択しました。テーマはその名の通り、iOSのプライベートAPIへアクセスすることです。
プライベートAPIとは
Appleはフレームワークの内部実装を非公開にしており、公式ドキュメントに載っていないクラスやメソッドが多数存在します。これらにアクセスすることはApp Storeへの提出では許可されませんが、デバッグや内部挙動の理解、テスト環境での活用といった用途には有効です。
探索ツール:headers.82flex.com
プライベートAPIを探す際には headers.82flex.com が有用です。iOSの内部ヘッダーが公開されており、クラス名やメソッド名を検索できます。ワークショップでは実際にこのサイトでメソッドを調べながら実装を進めました。
アクセス方法:value(forKey:) と perform(_:)
プライベートAPIへのアクセスには主に2つのアプローチを使います。
// プロパティアクセス(KVC: Key-Value Coding) let value = object.value(forKey: "privatePropertyName") // メソッド呼び出し(引数なしのシンプルなケース) object.perform(NSSelectorFromString("privateMethodName"))
NSObjectのKVC(Key-Value Coding)を利用したvalue(forKey:)でプロパティ値を取得し、perform(_:)で引数なしのメソッドを呼び出します。ただし、Int型などのprimitive引数を持つメソッドにはperformが使えないため、objc_msgSendを直接呼ぶC言語ヘルパーが必要になります。Obj-Cの型をSwiftに名前で公開したい場合は、Bridging Headerにヘッダーファイルをインポートすることで対応できます。
Objective-Cを書いていた頃にKVCの文脈でよく使っていたメソッドが登場し、懐かしさを感じながら作業しました。当時との違いは、SwiftUIからObj-Cの型を直接参照するためにBridging Headerへのヘッダーインポートが必要な点です。
挑戦:Face IDインターフェースの呼び出し
ワークショップ内ではFace IDのインターフェースをプライベートAPIで呼び出せないかを試みました。
内部ヘッダーを調べながら実装を進めましたが、最終的にFace ID認証の画面そのものを呼び出すことはできませんでした。一方で、Touch IDの登録画面を表示させることには成功しました。Face IDとTouch IDで内部的な仕組みが異なることを体感できた経験でした。

実際のプロダクト開発には使えないものの、iOSのシステム内部を覗く体験としては非常に刺激的なワークショップでした。
印象に残ったセッション
21セッションの中から、特に印象深かった3つを紹介します。
SwiftUIってなんでこうなるの? — Paul Hudson
発表者: Paul Hudson(@twostraws)
Paul Hudsonが「SwiftUIの内部構造を理解することでより良いコードが書ける」というテーマで発表しました。
最も印象的だったのは、@ViewBuilder内のif-elseが_ConditionalContentに変換されるという仕組みの解説です。
// ❌ @ViewBuilder内ではtrueとfalseが「別のView」として扱われる var body: some View { if scaleUp { TestView().scaleEffect(2) } else { TestView().scaleEffect(1) } } // → スケールアニメーションにならず、フェードイン/アウトになる
@ViewBuilderがif-elseを_ConditionalContent<TrueView, FalseView>に変換するため、SwiftUIは「2つの異なるView」として認識します。アニメーションではなくトランジションになるのはこのためです。
解決策は三項演算子を使うか、@ViewBuilderのない別プロパティに切り出すことです:
// ✅ 三項演算子で同一Viewの状態変化として扱わせる var body: some View { TestView().scaleEffect(scaleUp ? 2 : 1) }
if-elseやswitchによる分岐で表されるViewが内部的にそれぞれ異なるViewとして保持されているという点は、SwiftUIを深く理解する上での重要な知識です。アニメーションが意図通りに動かない原因がこの仕組みにあると知り、腑に落ちました。
Swiftの型システムはAIエージェントをどう導くのか — Yuta Koshizawa
発表者: Yuta Koshizawa( @koher )
スライド: SpeakerDeck
Swiftの型システムがAIエージェントのコーディング精度にどう影響するかを、実験データで示した発表です。
throwsが型の一部であることの意味
Swiftではthrowsが関数の型の一部です:
func findUser(name: String) throws -> User
TypeScriptなどの多くの言語では、関数がエラーを投げるかどうかは型の一部ではありません。宣言だけでは判断できず、コードを読む必要があります。
実験結果
Claude Codeを使って、SwiftとTypeScriptで同等のダミー関数群に対して同じタスク(エラーハンドリング付きの関数実装)を合計20回実施しました:
| 言語 | 正確なエラー処理(5回中) |
|---|---|
| Swift(throwing) | 5/5(100%) |
| Swift(non-throwing) | 5/5(100%) |
| TypeScript(throwing相当) | 0/5(0%) |
| TypeScript(non-throwing相当) | 2/5(40%) |
AIは関数宣言のみを確認してエラー処理の要否を判断しており、throwsの明示がない場合はコードを末端まで追跡しませんでした。
「より厳格なプロンプト」を与えたTypeScriptでも精度は80%に改善しましたが、入力トークン数が約2倍(187,900 → 400,000)に増加しました。Swiftではほぼ増加なし。
Swiftの型システム——特にthrowsが関数の型の一部として明示されること——が、AIエージェントのコンテキストそのものになり意図通りのアウトプットを可能にするという言説が非常に興味深かったです。
Swift 6でのActor isolationなど直近の破壊的変更に対して「なぜここまで型で縛るのか」と感じることもありましたが、それらの妥当性を補完する視点としても腑に落ちる内容でした。Swift言語への愛着がさらに高まるセッションでした。
XCUITestコード生成をAIに任せる — Yusuke Kita
発表者: Yusuke Kita( @kitasuke ) スライド: SpeakerDeck
E2Eテストパイプラインの構築を通じて発見した知見——「より良いプロンプト」ではなく「より良い構造(Structure)」が鍵——を語ったセッションです。
LLMがテストコードを書く際の3つの失敗パターン
LLMに「ログインテストを書いて」と指示すると、一見正しそうで動かないコードが生成されます:
| パターン | 説明 |
|---|---|
| 架空のセレクタ | 存在しないアクセシビリティIDを自信満々に生成 |
| 不正確なテキスト | 「Login」と「Sign in」の1単語の違いでテストが失敗 |
| 待機戦略の欠如 | CI環境での処理時間を考慮しない |
解決策:4レイヤーの構造化コンテキスト
詳細なプロンプトを書こうとするのが直感ですが、それではスケールしません。答えはLLMが読み取れるファイルを与えることです:
信頼できるAI生成テストコード = IR(何をテストするか) + Scenarios(どの手順か) + Definitions(何が存在するか) + Templates(どう書くか)
DefinitionsファイルにアクセシビリティIDや関数シグネチャを定義しておくことで「架空のセレクタ問題」を直接解決します。IDが変わっても1ファイルの更新で全テストに反映されます。
「AIのために構築するのではなく、チームのために構築してください」
この仕組みはAIのためだけに作られたわけではなく、チームのコンテキスト共有のために作られたもの。AIはたまたまこの構造の上でうまく機能しているだけ、という締めが印象的でした。
koherさんの「型がAIのコンテキストになる」という話との思想的な親和性が高く、「AIへのコンテキストをいかに構造化するか」という問いが、AI活用の本質的な課題だと改めて感じました。
まとめ
try!Swift Tokyoは今年で10周年を迎え、カンファレンスとしての体験やセッション、ワークショップのレベルも年々上がっておりApple プラットフォームに関わるエンジニアにとって最高の3日間になりました。
カンファレンス最終日、ふらっと立ち寄った店にtry! Swiftの参加者が自然と集まり、そこでの交流も印象的でした。 数年ぶりに再会できた方もおり、このような場の価値は、セッションの内容と同等かそれ以上にあると感じています。
try! Swift Tokyoは、世界中からAppleプラットフォームの開発者が集まる国内最大級のカンファレンスです。スキル向上はもちろん、同じ技術を扱う仲間との交流やキャリアを広げる場として最適です。
運営やスピーカーの皆様、そして参加者の皆様のおかげで、とても充実したカンファレンスでした。本当にありがとうございました。 また来年、参加できることを楽しみにしています。
