WWDC25:Meet WebKit for SwiftUI

とうとう WebView が SwiftUI に登場、WKWebViewUIViewRepresentable でラップして作り込んだり SFSafariViewController を使うべきか否か悩まなくて良くなるはず。JavaScript との連携や、特定位置スクロールなどもしっかりサポートされていて心強い。


0:00 – Introduction

  • WebKit は Safari, Mail、そして iOS, iPadOS, visionOS, macOS の無数のアプリの中核を担うブラウザエンジン
  • WebKit for SwiftUI の登場:全く新しい SwiftUI API により、Web コンテンツをアプリに統合することがより簡単に
  • 美しい Web コンテンツの表示が WebView を作成して URL を提供するだけで可能
  • WebKit がサポートする全プラットフォームで動作

1:54 – Load and display web content

  • WebView API の基本
    • 新しい SwiftUI ビューで Web コンテンツを簡単に表示
    • URL を提供するだけで自動的にロードして表示
    • 複数の URL の切り替えにも自動対応
      • WebView(url: toggle ? URL1 : URL2) で条件が切り替わるたびに自動的に新しい Web ビューが読み込まれる
  • WebPage クラスの活用
    • 新しい Observable クラスで Web コンテンツを表現
      • e.g. .navigationTitle(webPage.title) でタイトルを常に追従させる
    • Swift と SwiftUI と完璧に連携するよう設計
      • Web コンテンツの読み込み、コントロール、通信を行え、完全に単独で利用可能
      • WebView と組み合わせることで豊かな体験を構築
  • 多様なコンテンツロード方法
    • Loading URL requests:URLRequest を使用した load API
    • Loading HTML strings:HTML 文字列とベース URL を直接提供
    • Loading data:Web アーカイブデータ、MIME タイプ、文字エンコーディング、ベース URL を指定
  • URLSchemeHandler プロトコル
    • カスタムスキームの処理でアプリバンドル内のコンテンツやローカルファイルにアクセス
    • 独自の Scheme Handler を実装し、カスタムスキーム URL のナビゲーションを処理(e.g. lakes://
    • URLSchemeHandler プロトコルに準拠する型を作成し、reply 関数で URLSchemeTask 結果の async sequence を返す
      • URLResponse を含む URLSchemeTaskResultyield し、その後 Data を提供(同期的)
    • AsyncSequence により非同期データストリーミングも可能

9:37 – Communicate with the page

  • ナビゲーションイベントの観察
    • WebPagecurrentNavigationEvent プロパティでナビゲーション状態に簡単アクセス
    • Observable により SwiftUI と完璧に連携
  • ナビゲーションイベントタイプwebPage.currentNavigationEvent):
    • .startedProvisionalNavigation:ナビゲーション開始
    • .receivedServerRedirect:サーバーリダイレクト時
    • .committed:メインフレームのコンテンツ受信開始時
    • .finish:ナビゲーション完了時
    • .failed / .failedProvisionalNavigation:失敗時
  • Observations API との連携
    • Swift 6.2 の新しい Observations API を使用
    • currentNavigationEvent から async sequence を作成
    • for-await ループでイベント変化を観察
  • WebPage の observable なプロパティ
    • title, currentURL, estimatedProgress, themeColor など
  • JavaScript 通信
    • callJavaScript API で直接 JavaScript を評価
    • JavaScript 関数を記述し、callJavaScript で実行
    • 戻り値は optional Any なので、適切な Swift 型にキャスト
    • 引数辞書を提供可能:キーは JavaScript のローカル変数として表現
  • カスタムナビゲーションポリシー
    • WebPage.NavigationDeciding プロトコルでナビゲーションポリシーをカスタマイズ
    • ナビゲーションの異なるステップ(開始前、レスポンス受信時、認証時)でポリシー(allow / cancel)を指定
    • NavigationActionNavigationPreferences を使用してナビゲーションを制御

15:44 – Customize content interaction

  • スクロール動作のカスタマイズ
    • .scrollBounceBehavior modifier で標準的なスクロール動作を制御
    • 垂直・水平軸のバウンス動作を個別に設定可能
    • basedOnSize オプションでコンテンツサイズに基づくバウンス制御
  • visionOS での Look to Scroll
    • .webViewScrollInputBehavior modifier で Look to Scroll を設定
    • デフォルトでは無効、enabled に設定することで有効化
  • Find-In-Page サポート
    • 既存の .findNavigator modifier が WebView と完璧に連携
    • iOS/iPadOS:オンスクリーンキーボード表示時または WebView 下部に表示
    • macOS/visionOS:WebView 上部に表示
  • スクロール位置の制御
    • .webViewScrollPosition modifier でスクロール位置を WebView に関連付け
    • scrollTo を使用して特定の位置にスクロール
    • JavaScript と連携してセクション位置を計算
  • スクロールジオメトリの監視
    • .onScrollGeometryChange modifier でスクロールジオメトリの変更を監視
    • コンテンツオフセットやサイズなどの変更に対応
    • 変換関数を使用して特定の値の変更時にクロージャを実行
    • 選択されたセクションとスクロール位置の同期が可能