SwiftUI

UIKit to SwiftUI Migration 2026 – Step Guide

ⓘ本ページはプロモーションが含まれています

スポンサードリンク

移行戦略全体像と選択基準

UIKit ベースの既存プロジェクトを安全に SwiftUI にシフトするには、「どこまで置き換えるか」「誰が担当するか」 を明確にした上で、段階的なパターンを選定することが成功の鍵です。本セクションでは、代表的な 3 つの移行パターンと、各パターンを採用すべき判断基準を示します。

ハイブリッド埋め込みパターン(UIKit → SwiftUI)

このパターンは、既存の UIKit 画面に新規機能だけを SwiftUI で実装し、UIHostingController を介して差し込む手法です。リスクが低く、Storyboard や XIB の資産をそのまま活用できます。

実装上の留意点

  1. View の定義 – SwiftUI 側は struct MyFeatureView: View と宣言し、状態管理は @State@ObservedObject を利用します。
  2. 画面遷移 – UIKit からは UIHostingController(rootView:) を生成し、pushViewController(_:animated:)present(_:animated:) で表示します。

ポイントUIHostingController のサイズが正しく計算されないケースは、preferredContentSize もしくは Auto Layout 制約で明示的に指定してください。


UIKit コンポーネント埋め込みパターン(SwiftUI → UIKit)

SwiftUI が主導権を握る画面でも、既存のカスタム UIViewUIViewController をそのまま利用したい場合があります。このときは UIViewRepresentableUIViewControllerRepresentable にラップします。

実装上の留意点

  • 最小実装makeUIView(context:)updateUIView(_:context:) のみ実装し、不要なメソッドは省略します。
  • デリゲート橋渡しCoordinator を用いて UIKit デリゲートを SwiftUI 側に転送する際は、循環参照に注意し weak 参照を必ず使用します。


完全リプレイスの判断ポイント

全画面を一度に SwiftUI に置き換える「完全リプレイス」は、コストと効果を慎重に比較したうえで決定します。以下の表は、判断材料として活用できるチェック項目をまとめたものです。

判断基準 説明
大規模 UI 改修が既に計画されているか 既存コードを残すコストが上回るケースでは、リプレイスが有利です。
チーム全体の SwiftUI 熟練度 メンバーが @StateObservableObject に慣れていれば学習コストは低減します。
iOS の新機能活用意欲 NavigationStackRefreshable など宣言的 API をフル活用できるかを評価します。
メンテナンス体制の整備 CI/CD パイプラインで SwiftUI ビルドが問題なく通過するか確認してください。

結論:多くのプロジェクトは ハイブリッド埋め込みパターン から開始し、要件が拡大したタイミングで 段階的に完全リプレイス へシフトすることが現実的です。


ブリッジ API と宣言的コンポーネント活用ガイド

SwiftUI と UIKit を橋渡しするための公式ブリッジ API は、Xcode 15 系で安定化しています。本セクションでは、代表的な API のベストプラクティスと、iOS 17 以降に追加された宣言的コンポーネントの活用例を紹介します。

UIHostingController のベストプラクティス

UIHostingController は SwiftUI View を UIKit に埋め込む際の中心的手段です。以下は、実装時に考慮すべきポイントです。

  1. ライフサイクル統合SceneDelegate は iOS 13 以降非推奨です。@UIApplicationDelegateAdaptor と組み合わせた SwiftUI App ライフサイクルで管理します。
  2. サイズ調整 – Auto Layout と連動させるために preferredContentSize を設定し、必要なら ignoresSafeArea() で安全領域を明示的に扱います。
  3. エラーハンドリング – 初期化時の失敗は基本的に起こりませんが、ルート View が依存するデータ取得は Taskdo‑catch で包み、UI にフィードバックします。

参照:Apple Developer Documentation – UIHostingController (2024 年 3 月版)
URL: https://developer.apple.com/documentation/swiftui/uihostingcontroller


UIViewRepresentable / UIViewControllerRepresentable の実装ガイド

基本構造とメモリ管理

実装項目 推奨コード
makeUIView でのインスタンス生成 必要最小限の設定だけ行い、外部リソースは遅延ロードする
updateUIView の副作用回避 UI の状態更新のみを行い、重い処理は Task.detached に委譲
Coordinator でのデリゲート橋渡し weak var parent: Self? として循環参照を防止


iOS 17 で追加された宣言的コンポーネント例

iOS 17 では contextMenu 修飾子が拡張され、カスタムプレビューやインタラクティブアクションをコードだけで記述できるようになりました。以下は実装サンプルです。

注意:iOS 16 未満のデバイスでは contextMenu の拡張機能は無効化されるため、ビルド時に条件コンパイル (if #available(iOS 17, *)) を入れると安全です。


プロジェクト設定と移行チェックリスト

UIKit → SwiftUI に切り替える際に見落としがちなのは、Xcode のビルド設定や Info.plist の項目です。ここでは、2024 年現在の Xcode 15.3 / Swift 5.10 を前提とした推奨設定をまとめます。

SwiftUI App ライフサイクルへの移行手順

  1. プロジェクトに @main エントリーポイントとなる構造体(例:MyApp)を作成し、App プロトコルに準拠させます。
  2. 既存の AppDelegate が必要な場合は、@UIApplicationDelegateAdaptor で保持します。
  3. Info.plistMain storyboard file base name を削除し、Storyboard が自動ロードされないようにします。


ビルド設定・Info.plist 更新ポイント

設定項目 推奨値 補足
Enable Multiple Windows YES(iOS 17 以降) SwiftUI のマルチウィンドウを有効化
Swift Language Version 5.10 以上 Xcode 15 系の最適化コンパイラを利用
Targeted Device Family iPhone, iPad 両プラットフォームで単一コードベースを維持
UIUserInterfaceStyle Unspecified ダークモードは SwiftUI が自動対応
Storyboard Name (Info.plist) 削除または空白 Storyboard 起動を防止

移行チェックリスト(実践版)

  • [ ] @main 構造体の作成とビルド成功
  • [ ] Info.plist から Main storyboard file base name を除去
  • [ ] Enable Multiple Windows を有効化し、シミュレータで動作確認
  • [ ] Swift コンパイラバージョンを 5.10 に統一(プロジェクト設定 → Build Settings)
  • [ ] ハイブリッド画面 1 件以上を UIHostingController で実装し、テスト対象に含める

参考:Apple Developer – Migrating an App from UIKit to SwiftUI (2024 年版)
URL: https://developer.apple.com/documentation/swiftui/migrating-an-app-from-uikit-to-swiftui


アーキテクチャ見直し:MVVM + Coordinator と ViewModel のプロトコル設計

UIKit と SwiftUI が混在するコードベースでは、ビジネスロジックを UI から切り離す 設計が不可欠です。本節では、Protocol‑Driven MVVM に Coordinator を組み合わせた構成例と、テストしやすい ViewModel の実装パターンを示します。

アーキテクチャ全体像

  • Coordinator が画面遷移を一元管理し、UIKit と SwiftUI の両方から呼び出せる。
  • ViewModelObservableObject に準拠したプロトコルで定義し、依存性注入によりテストが容易になる。

ViewModel プロトコルと実装例(エラーハンドリング付き)

  • エラーハンドリングCombinesink で完了時に処理し、UI 側は errorMessage を監視してトースト表示などを行います。
  • 循環参照防止のため、[weak self] を必ず付与しています。

UIKit と SwiftUI の両方で ViewModel を利用する例


単体テスト戦略

テスト対象 手法
ViewModel のロジック XCTest + Mock Service(UserServiceProtocol をモック実装)
Coordinator の遷移 UI テスト (XCTestXCUIApplication) で画面遷移を検証
SwiftUI View のバインディング ViewInspector ライブラリで状態変化を確認


実務で直面しやすい落とし穴と対策

段階的に移行を進める際、特有のバグやパフォーマンス課題が頻発します。ここでは、代表的な問題例と具体的な解決手順を示します。

レイアウト崩れの主な原因と修正テクニック

原因 修正策
UIHostingController のサイズ制約が不足 preferredContentSize と Auto Layout を併用し、必要なら heightAnchor.constraint(equalToConstant:) で明示指定
SwiftUI の Spacer がナビゲーションバーと競合 .padding(.top, safeAreaInsets.top)ignoresSafeArea(edges: .top) を組み合わせて調整
動的型サイズ (Dynamic Type) 未対応 SwiftUI では font(.body).dynamicTypeSize(... )、UIKit では adjustsFontForContentSizeCategory = true を設定

パフォーマンス低下へのプロファイル手法

  1. Instruments – SwiftUI Rendering
  2. フレームごとの描画コストを測定し、過剰な再描画が起きている View を特定。
  3. バックグラウンド処理の分離
  4. 重い計算は Task.detached に委譲し、UI スレッドへの負荷を回避。
  5. リスト表示の最適化
  6. 大量データは LazyVStackListdiffableDataSource の併用でセル再利用効率を向上させる。

アクセシビリティ維持チェックポイント

項目 実装例
VoiceOver ラベル付与 SwiftUI: .accessibilityLabel("ユーザー名")、UIKit: view.isAccessibilityElement = true; view.accessibilityLabel = "ユーザー名"
Dynamic Type 対応 SwiftUI: font(.title).scaledToFit()、UIKit: label.adjustsFontForContentSizeCategory = true
カラーコントラスト カスタム色は UIColor(dynamicProvider:) で明暗モードに自動対応させる

ブランド適合性ガイドライン

本記事を社外・社内問わず配布する際には、以下のブランドポリシーに従ってください。

  1. ロゴ使用 – 企業ロゴは公式ロゴファイル(SVG/PNG)以外で表現しないこと。サイズは最低 48 × 48 px、余白はロゴ周囲の 20 % を確保。
  2. トーン&マナー – カジュアル過ぎず、かつ技術的に正確な表現を心掛ける。「です・ます」調で統一し、主観的な評価語(「最高」「絶対おすすめ」)は避ける。
  3. フォント・配色 – 公式ドキュメントのガイドラインに準拠した Noto Sans JP(本文)と Roboto Mono(コードブロック)を使用し、背景は白またはライトグレーで統一する。
  4. リンク表記 – 外部サイトへの参照は必ず公式ドメインか信頼できる情報源に限定し、URL はフルパスで表示して読者が直接確認できるようにする。

次のアクション:チェックリスト活用とタスクプラン

この記事で提示した移行戦略・ブリッジ API・アーキテクチャ設計を踏まえ、実際のプロジェクトで以下のステップを順次実施してください。

  1. 依存関係洗い出し
  2. 現行コードベースの UI コンポーネントリストを作成し、ハイブリッド化対象を 2〜3 画面に絞る。
  3. ブランチ戦略と実験環境構築
  4. migration/hybrid ブランチを作成し、Xcode 15.3 の設定変更(Swift バージョン・Info.plist)を行う。
  5. ハイブリッド画面実装
  6. 先ほど選定した画面に UIHostingController を導入し、エラーハンドリングとサイズ調整を組み込む。
  7. アーキテクチャ統合
  8. MVVM + Coordinator の骨格を共通モジュールとして抽出し、ViewModel プロトコルで UI 層を抽象化する。
  9. 品質保証
  10. Unit Test(ViewModel)と UI Test(Coordinator・画面遷移)を追加し、CI パイプラインで自動実行。
フェーズ 主なタスク 想定スプリント (2 週間) 外注費用概算*
調査・設計 移行戦略策定、ブリッジ API 評価 1 ¥150,000〜¥250,000
ハイブリッド実装① UIHostingController による 2 画面置換 2 ¥300,000〜¥450,000
アーキテクチャ統合 MVVM + Coordinator の共通化、ViewModel プロトコル化 2 ¥350,000〜¥500,000
品質保証・調整 Instruments によるパフォーマンス測定、アクセシビリティチェック 1 ¥120,000〜¥200,000

*金額は一般的な外注相場(2024 年度)を参考にした概算です。実際の見積もりはベンダーと協議してください。

参考リンク:株式会社Classic の移行費用解説(2024 年版)
URL: https://classic.co.jp/media/column/uikit-to-swiftui-migration-cost/


まとめ

  • 段階的ハイブリッド が最もリスク低減しやすく、完全リプレイス は要件が固まってから検討
  • UIHostingControllerUIViewRepresentable 系 API の正しい使い方とエラーハンドリングで安定性を確保
  • MVVM + Coordinator による層分離で UIKit と SwiftUI が同居してもロジックの重複を防止
  • ビルド設定・Info.plist の更新、チェックリストに沿ったテスト体制構築が移行成功の必須条件

上記ガイドラインとタスクプランをチームで共有し、スプリント単位で着実に進めていけば、2024 年現在の最新ツールチェーンでも安全かつ効率的に UIKit から SwiftUI への移行が達成できます。


スポンサードリンク

-SwiftUI