1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

各社の採用アーキテクチャとMVVM

Last updated at Posted at 2025-03-06

まえがき

昨日書いた記事の反響をいただき、返信を考えていたら急に自信がなくなってきた。

思い切ってMVVMとして書いたコードだが、このViewManagerの解釈はひとりよがりなものではないだろうか…。

そこでいくつか技術記事を調べたものの、どうもViewModelとは何かがしっくりこない。

そもそも、皆さんMVVMってどう解釈しているのだろう…?!

しらべてみた

実務の場でSwiftに全く触れておらず、肌感覚が自分には全くわからない。
そこで、相棒ぐろ君(Grok)にお願いして、DeepResearchで各企業の採用アーキテクチャを調べてもらい、一覧化してもらった。

その結果が以下の通り。
※引用元のURLについて、このあとのMVVMのものも同様ですが、リンクが正しくないようです。
余裕のある時に、修正をお願いしてリンクを修正いたします。
申し訳ありません。

調査結果

◎調査依頼開始時に「MVVMやTCAなどのアーキテクチャ…」と伝えたため、ぐろ君はMVVMとTCAで当初検索したようです。追加で他のアーキテクチャは何があるかを示させた上で検索をしてもらい、MVやCleanArchitectureが出てきています。
表の印象ではMVVMかSwiftUIならTCA一択か?!となりそうですが、実態としてはMVやCleanArchitectureがもっと多くありそうです。

会社名 UI アーキテクチャ 備考 出典
株式会社カウシェ SwiftUI + UIKit MVVM SwiftUIを主に使用しつつ、一部UIKitを併用。ViewModelを分割しテスト容易性を確保。 カウシェ技術ブログ(2023年)
株式会社ミンネ SwiftUI + UIKit MVVM(一部TCA検討) SwiftUIとUIKit混在。Repository層でデータ管理を集中化。 ミンネテックブログ(2023年)
OpenWork株式会社 UIKit(SwiftUI予定) MVVM → TCA TCAへ移行中。UIKit+Combineを使用し、1画面ずつTCA化を進行。 OpenWorkテックブログ(2023年)
freee株式会社 SwiftUI TCA 新規アプリでSwiftUI+TCAを採用。Reducerをセクション単位で分割。 freee技術ブログ(2023年)
株式会社ニューズピックス SwiftUI + UIKit TCA UIKitからSwiftUI+TCAへ移行中。XIB廃止しセルをSwiftUI化。 NewsPicksテックブログ(2023年)
コネヒト株式会社 SwiftUI + UIKit MVVM SwiftUI導入もiOS 13サポートのためUIKit併用。RxSwiftを継続使用。 コネヒト技術ブログ(2023年)
リクルート株式会社 UIKit(SwiftUI移行検討) MVVM + Layered UIKit中心だがSwiftUI移行を計画。Embedded Frameworkでコード共有。 リクルート技術ブログ(2019年)
株式会社LayerX SwiftUI(一部UIKit) MVVM + 独自アレンジ 新規機能はSwiftUIで実装。View分割とCombineで最適化。 LayerXテックブログ(2023年)
株式会社リモートワークス SwiftUI TCA 新規アプリでSwiftUI+TCAをフル採用。Reducerをモジュール化。 技術勉強会資料(2024年)
株式会社FiNC Technologies SwiftUI + UIKit MVVM ヘルスケアアプリでSwiftUI導入。プレビュー機能でデザイナー連携を強化。 FiNCテックブログ(2023年)
株式会社SmartHR SwiftUI(新規のみ) MVVM 新機能でSwiftUIを試験導入。プロトタイピングを迅速化。 SmartHRブログ(2024年)
株式会社Drecom SwiftUI TCA ゲーム関連ツールでSwiftUI+TCAを採用。ゲームロジックにReducerを適用。 Drecomテックブログ(2023年)
株式会社HERMES SwiftUI MVVM 受託開発でSwiftUIをフル採用。コード量削減を重視。 インタビュー記事(2024年)
株式会社LegalOn Technologies SwiftUI + UIKit MVVM 法務支援アプリでSwiftUI導入。NavigationStackをカスタマイズ。 LegalOnテックブログ(2023年)
株式会社カミナシ SwiftUI MVVM 現場管理アプリでSwiftUI採用。Combineでリアルタイム更新を効率化。 カミナシブログ(2024年)
株式会社マネーフォワード SwiftUI + UIKit MVVM 一部画面をSwiftUIで再構築。モジュラー化を推進。 マネーフォワードブログ(2023年)
株式会社ANDPAD SwiftUI + UIKit MVVM 建築現場管理アプリでSwiftUI試験導入。プレビューでUI調整を効率化。 ANDPAD技術ブログ(2024年)
株式会社Luup SwiftUI TCA 電動キックボードアプリでSwiftUI+TCA採用。副作用管理を活用。 Luupブログ(2023年)
株式会社クラッソーネ SwiftUI MVVM 解体工事見積もりアプリでSwiftUIフル採用。アニメーションを活用。 クラッソーネブログ(2024年)
株式会社TRIDENT SwiftUI MVVM 教育アプリでSwiftUI採用。迅速なプロトタイプ作成を重視。 インタビュー記事(2023年)
株式会社Speee SwiftUI + UIKit MVVM 不動産アプリでSwiftUI試験導入。モジュール間依存を最小化。 Speeeテックブログ(2024年)
株式会社リモートウェル SwiftUI MVVM リモートワークツールでSwiftUI採用。シンプルな設計を追求。 技術ブログ(2024年)
株式会社HEROZ SwiftUI + UIKit MVVM AI将棋アプリでSwiftUI試験導入。盤面描画はUIKit依存。 HEROZテックブログ(2023年)
株式会社プレイド SwiftUI TCA CX管理ツールでSwiftUI+TCA採用。状態管理の一貫性を重視。 プレイド技術ブログ(2024年)
株式会社リモハブ SwiftUI MVVM 健康管理アプリでSwiftUIフル採用。迅速な開発を優先。 インタビュー記事(2023年)
株式会社リンクアンドモチベーション SwiftUI + UIKit MVVM エンゲージメントアプリでSwiftUI導入。既存UIKitと互換性維持。 技術ブログ(2024年)
株式会社BASE SwiftUI MVVM ECアプリ新機能でSwiftUI採用。Combineでデータバインディング。 BASEテックブログ(2023年)
株式会社メンバーズ SwiftUI TCA マーケティングツールでSwiftUI+TCA採用。テスト容易性を重視。 メンバーズブログ(2024年)
株式会社ビットキー SwiftUI + UIKit MVVM スマートロックアプリでSwiftUI試験導入。セキュリティ機能はUIKit。 ビットキーブログ(2023年)
株式会社リザーブリンク SwiftUI MVVM 予約管理アプリでSwiftUIフル採用。保守性を重視した設計。 リザーブリンクブログ(2023年)
株式会社オクト SwiftUI + UIKit TCA 社内ツールでSwiftUI+TCA採用。モジュール化を推進。 オクトブログ(2024年)
株式会社VOYAGE GROUP SwiftUI MVVM アドテクアプリでSwiftUI採用。軽量なUI実装を優先。 VOYAGEブログ(2023年)
株式会社サイバーエージェント SwiftUI + UIKit MVVM 「Ameba」でSwiftUI試験導入。既存コードとの統合を重視。 CyberAgentブログ(2024年)
株式会社ワークスアプリケーションズ SwiftUI TCA ERPアプリ新機能でSwiftUI+TCA採用。一貫した状態管理を追求。 ワークスブログ(2023年)
株式会社レアゾン SwiftUI MVVM AIチャットアプリでSwiftUI採用。迅速なUI開発を重視。 インタビュー記事(2024年)
株式会社ラクス SwiftUI + UIKit MV 業務支援アプリでSwiftUI採用。ViewModelを省略しシンプルさを追求。 ラクス技術ブログ(2024年)
株式会社ドワンゴ SwiftUI + UIKit MVVM 「ニコニコ」アプリでSwiftUI試験導入。既存コードとの統合を重視。 ドワンゴ技術ブログ(2023年)
株式会社はてな SwiftUI MV 「はてなブックマーク」新機能でSwiftUI採用。軽量なMVパターンを使用。 はてな技術ブログ(2024年)
株式会社メルカリ SwiftUI + UIKit Clean Architecture 一部新機能でSwiftUI+Clean採用。依存関係を明確化し拡張性を重視。 メルカリ技術ブログ(2023年)
株式会社クックパッド SwiftUI MVVM レシピアプリ新機能でSwiftUI採用。データバインディングを最適化。 クックパッド技術ブログ(2024年)
株式会社リモート SwiftUI MV リモートワーク支援ツールでSwiftUI採用。シンプルなMVで迅速開発。 インタビュー記事(2023年)
株式会社チームラボ SwiftUI + UIKit MVVM アート関連アプリでSwiftUI導入。クリエイティブなUIを重視。 チームラボ技術ブログ(2023年)
株式会社サイボウズ SwiftUI Clean Architecture グループウェア新機能でSwiftUI+Clean採用。テスト性を強化。 サイボウズ技術ブログ(2024年)
株式会社Sansan SwiftUI + UIKit MVVM 名刺管理アプリでSwiftUI試験導入。既存UIKitと連携。 Sansan技術ブログ(2023年)
株式会社Preferred Networks SwiftUI TCA AIツールでSwiftUI+TCA採用。状態管理の一貫性を重視。 PFN技術ブログ(2024年)

きいてみた

この結果を受けて、偏向はあるものの、それでも当初思っていたよりMVVMが多いことを確認できた。
そこで、洗い出しがある程度できた段階で、以下の質問をぐろ君になげかけてみた。

ところで、Swiftのアーキテクチャに関する有名な日本の書籍を書いた方は、SwiftUIにおいてはMVVMのViewModelは不要だと話していました。
SwiftUIを使いMVVMを採用している企業では、ViewModelにどのような役割を持たせているのでしょうか。freeeではTCAの採用にあたり、MVVMはメンバーごとに記載が変わる懸念があるため不採用とした経緯をブログに記載していましたが、そもそもMVVMのViewModelはどのような役割を持ち、どう記載すべきなのかがはっきりしないように思います。
SwiftUIかつMVVMとなっている企業について、それぞれのMVVMの詳細をまとめてください。

この回答が、以下。

ご質問ありがとうございます!確かに、SwiftUIにおけるMVVMのViewModelの必要性や役割については、議論の多いトピックです。SwiftUIの宣言的性質や組み込みの状態管理機能(@Stateや@ObservableObjectなど)が、従来のMVVMにおけるViewModelの役割を一部代替してしまうため、「MVVMは不要」とする意見も根強いですね。一方で、SwiftUIでMVVMを採用している企業では、ViewModelに具体的な役割を持たせ、独自の解釈や工夫を加えているケースが見られます。

以下では、まずSwiftUIにおけるMVVMのViewModelの一般的な役割と課題について整理した後、SwiftUIかつMVVMを採用している企業について、技術ブログや公開情報に基づき、その詳細をまとめます。特に、各社のViewModelがどのような役割を担い、どのように実装されているかを可能な限り明確にします。

この「以下では」を、そのまま流用してしまいます。

SwiftUIにおけるMVVMのViewModelの役割と課題

一般的な役割

MVVMのViewModelは、以下のような役割を持つとされています:

  1. データ変換: Modelの生データをViewが表示しやすい形に変換する(例: 日付を文字列にフォーマット)。
  2. 状態管理: Viewに表示するための状態(UI状態)を保持し、変更を通知する(SwiftUIではObservableObjectを活用)。
  3. ビジネスロジック: 軽量なビジネスロジックや入力バリデーションを処理する。
  4. ViewとModelの分離: ViewがModelに直接依存しないよう、中間層として機能する。

SwiftUIでは、@State@Binding@ObservableObjectが状態管理を簡素化するため、ViewModelがなくてもViewとModelを直接つなげられるケースが多いです。そのため、ViewModelを導入する場合は、上記の役割を明確に定義し、不要な複雑さを避ける必要があります。

課題と議論

  • 役割の曖昧さ: freeeが指摘するように、MVVMのViewModelの役割は開発者やチームによって解釈が異なりがちで、「何をどこまで担当するか」が曖昧になりやすい。
  • SwiftUIとの相性: SwiftUIの宣言的UIでは、Viewが状態変化に即座に反応するため、ViewModelが単なる中間層として冗長に感じられる場合がある。
  • テスト容易性とのトレードオフ: ViewModelを導入することでテストが容易になる一方、シンプルなアプリではオーバーヘッドが増える。

freeeがTCAを採用した理由として挙げた「MVVMはメンバーごとに記載が変わる懸念」は、この曖昧さがチーム開発での一貫性を損なうリスクを示しています。では、実際にMVVMを採用している企業では、どのようにViewModelを定義し、実装しているのでしょうか?

SwiftUI×MVVMにおけるViewModelの役割

どう実装されているのか、文章形式だとわかりにくいため、縦に並べて比較できるよう、表にまとめてもらった。
印象としては、Repository的な役割で表示用データを管理する場合と、単に表示の状態を管理する軽量な場合の大まかな2通りの使われ方をしているようである。
以下に、まとめてもらった表とその総括を、またそのまま流用して貼り付けます。

SwiftUIかつMVVMを採用している企業の詳細

以下は、SwiftUIかつMVVMを採用している企業のViewModelの役割を「データ変換」「状態管理」「その他のロジック」に分類し、技術ブログや公開情報に基づいてまとめたものです。

会社名 UI データ変換 状態管理 その他のロジック 実装の詳細・備考 出典
株式会社カウシェ SwiftUI + UIKit 商品詳細(価格、在庫数)をView用に変換 在庫状況や価格変更をリアルタイムで反映 ボタンの有効/無効判定 ViewModelはObservableObjectでCombineを使用。複雑なUIはUIKitで補完。 カウシェ技術ブログ(2023年)
株式会社ミンネ SwiftUI + UIKit 商品一覧や作家情報をView向けに整形 商品の「お気に入り」や検索結果を管理 リポジトリ連携 画面単位でViewModelを定義。RxSwiftで非同期処理を補完。 ミンネテックブログ(2023年)
コネヒト株式会社 SwiftUI + UIKit QAデータ(投稿日時)を「〇分前」に変換 投稿の表示状態(読み込み中、完了、エラー) ユーザー入力処理 ViewModelはObservableObjectでRxSwiftを使用。iOS 13サポートでUIKit併用。 コネヒト技術ブログ(2023年)
株式会社LayerX SwiftUI(一部UIKit) 請求書データ(金額)をカンマ区切りに変換 請求書リストの選択状態やフィルタ条件を管理 軽量な計算(合計金額) ViewModelはObservableObjectで再描画最適化。UIKitは互換性維持に限定。 LayerXテックブログ(2023年)
株式会社FiNC Technologies SwiftUI + UIKit ヘルスケアデータをグラフ表示用に整形 グラフ表示状態やユーザー入力(体重)を管理 プレビュー用ダミーデータ提供 ViewModelはObservableObjectでCombineを使用。複雑なグラフはUIKit依存。 FiNCテックブログ(2023年)
株式会社SmartHR SwiftUI(新規のみ) 人事データ(社員リスト)をフィルタリング 選択された社員やフォーム状態を保持 プロトタイピング用軽量ロジック ViewModelは新規機能限定でObservableObjectを使用。既存はUIKitベース。 SmartHRブログ(2024年)
株式会社HERMES SwiftUI クライアントデータをView向けに整形 表示状態(ロード中、完了)を管理 複雑な処理はModelに委譲 ViewModelはObservableObjectでコード量削減。小規模プロジェクト向け。 インタビュー記事(2024年)
株式会社LegalOn Technologies SwiftUI + UIKit 法務書類データ(契約書項目)をリスト化 フォーム入力やナビゲーション状態を管理 NavigationStackのカスタマイズ ViewModelはObservableObjectでCombineを使用。複雑なフォームはUIKit依存。 LegalOnテックブログ(2023年)
株式会社カミナシ SwiftUI 現場データをリアルタイム表示用に整形 データ更新やエラー状態を管理 API呼び出しをViewModel内で処理 ViewModelはObservableObjectでCombineを使用。小規模チーム向けにシンプル化。 カミナシブログ(2024年)
株式会社マネーフォワード SwiftUI + UIKit 家計簿データ(カテゴリ集計)を変換 表示モード(リスト/グラフ)や選択状態を管理 UIKitコードとのブリッジ調整 ViewModelはObservableObjectでモジュール性重視。移行段階での柔軟性を確保。 マネーフォワードブログ(2023年)
株式会社クラッソーネ SwiftUI 見積もりデータをView向けに整形 見積もり入力やアニメーション状態を管理 入力データをModelに反映 ViewModelはObservableObjectでアニメーション支援。ユーザー体験を重視。 クラッソーネブログ(2024年)
株式会社TRIDENT SwiftUI 教育コンテンツデータを整形 表示状態やユーザー進捗を管理 プロトタイピング用軽量ロジック ViewModelはObservableObjectで小規模開発向け。迅速な試作を優先。 インタビュー記事(2023年)
株式会社Speee SwiftUI + UIKit 不動産データをView向けに変換 検索条件や選択状態を管理 UIKitとの依存最小化 ViewModelはObservableObjectでモジュール分離。試験導入段階。 Speeeテックブログ(2024年)
株式会社リモートウェル SwiftUI リモートワークツールデータを整形 ツール使用状況を管理 軽量ロジックのみ ViewModelはObservableObjectでシンプル設計。小規模アプリ向け。 技術ブログ(2024年)
株式会社HEROZ SwiftUI + UIKit 将棋データをView向けに変換 盤面の表示状態を管理 UIKit描画との同期 ViewModelはObservableObjectでCombine使用。AI将棋アプリ向け。 HEROZテックブログ(2023年)
株式会社リモハブ SwiftUI 健康管理データをView向けに整形 健康データ更新状態を管理 軽量ロジックで迅速開発 ViewModelはObservableObjectで迅速開発支援。小規模アプリ向け。 インタビュー記事(2023年)
株式会社リンクアンドモチベーション SwiftUI + UIKit エンゲージメントデータを変換 社員データの表示状態を管理 UIKitとの連携調整 ViewModelはObservableObjectで既存コード統合。互換性重視。 技術ブログ(2024年)
株式会社BASE SwiftUI ECデータをView向けに整形 商品選択や表示状態を管理 Combineでリアルタイム更新 ViewModelはObservableObjectで新機能向け。データバインディング重視。 BASEテックブログ(2023年)
株式会社ビットキー SwiftUI + UIKit スマートロックデータを変換 ロック状態を管理 セキュリティ機能と連携 ViewModelはObservableObjectでセキュリティ調整。セキュリティ重視。 ビットキーブログ(2023年)
株式会社リザーブリンク SwiftUI 予約データをView向けに整形 予約状況を管理 シンプルなロジックで保守性確保 ViewModelはObservableObjectで保守性重視。予約管理アプリ向け。 リザーブリンクブログ(2023年)
株式会社VOYAGE GROUP SwiftUI アドテクデータをView向けに整形 表示状態を管理 軽量なUI実装支援 ViewModelはObservableObjectで軽量設計。アドテクアプリ向け。 VOYAGEブログ(2023年)
株式会社サイバーエージェント SwiftUI + UIKit 「Ameba」データをView向けに変換 ブログ表示状態を管理 既存UIKitコードとの統合 ViewModelはObservableObjectで試験導入。統合重視。 CyberAgentブログ(2024年)
株式会社レアゾン SwiftUI AIチャットデータをView向けに整形 チャット状態を管理 UI開発の迅速化 ViewModelはObservableObjectで小規模向け。AIアプリ向け。 インタビュー記事(2024年)
株式会社ラクス SwiftUI + UIKit 業務支援データをView向けに変換 業務フローの状態を管理 軽量ロジックでシンプル化 ViewModelはObservableObjectでUIKit連携。シンプルさ重視。 ラクス技術ブログ(2024年)
株式会社ドワンゴ SwiftUI + UIKit 「ニコニコ」動画データをView向けに整形 再生状態を管理 既存UIKitコードとの調整 ViewModelはObservableObjectで試験導入。既存アプリ統合。 ドワンゴ技術ブログ(2023年)
株式会社クックパッド SwiftUI レシピデータをView向けに整形 レシピ選択状態を管理 データバインディング最適化 ViewModelはObservableObjectで新機能向け。テスト性重視。 クックパッド技術ブログ(2024年)
株式会社チームラボ SwiftUI + UIKit アートデータをView向けに変換 表示状態を管理 クリエイティブな挙動支援 ViewModelはObservableObjectでUIKit連携。アートアプリ向け。 チームラボ技術ブログ(2023年)
株式会社Sansan SwiftUI + UIKit 名刺データをView向けに整形 名刺リストの状態を管理 既存UIKitコードと同期 ViewModelはObservableObjectで試験導入。名刺管理アプリ向け。 Sansan技術ブログ(2023年)

総括と考察

ViewModelの役割の傾向

  • データ変換と状態管理が中心: ほとんどの企業で、ViewModelはModelデータの整形とViewの状態管理を担当。SwiftUIのObservableObject@Publishedを活用し、リアルタイム更新を実現。
  • 軽量ロジックの集約: 入力バリデーションや簡単な計算をViewModelに持たせ、複雑なビジネスロジックはModelや別層に分離する傾向。
  • UIKitとの橋渡し: SwiftUIとUIKitが混在する場合、ViewModelが互換性を保つ役割を担う(例: マネーフォワード、LegalOn)。

freeeの懸念との関連

freeeが「MVVMはメンバーごとに記載が変わる」と懸念した点は、上記の企業でも微妙な違いとして現れています:

  • 役割の範囲: 例えば、カウシェやLayerXでは軽量なビジネスロジックをViewModelに含める一方、HERMESやカミナシでは極力シンプルに保ち、Modelにロジックを委譲。
  • 実装スタイル: Combineを使う企業(LayerX、カミナシ)とRxSwiftを併用する企業(コネヒト)で、非同期処理のアプローチが異なる。

どう記載すべきか?

  • 明確なガイドラインが必要: ViewModelの役割をチーム内で事前に定義(例: データ変換のみ、状態管理のみ、軽量ロジックまで)し、文書化する。
  • 一貫性を保つ命名と構造: SearchViewModelのように画面単位でViewModelを定義し、役割を明示的にコメントやプロトコルで規定。
  • SwiftUIの特性を活かす: @ObservableObjectを基本とし、必要以上の抽象化(例: 過剰なプロトコル)は避ける。

SwiftUIの特性上、ViewModelは「Viewのためのデータホルダー」としてシンプルに保つのが理想的です。一方で、複雑なアプリでは、freeeのようにTCAやClean Architectureを採用し、役割の曖昧さを排除する選択肢も有効かもしれません。

まとめ

実務経験がなく現役のSwiftエンジニアとはほぼ全く会話したことがない私であったが、DeepResearchの力を借り、視野と深さを持つ地に足のついた検討ができたように思う。

調査開始前は、現場のエンジニアの総意としてViewModelがどう考えられているのか全くわからない状況であった。
しかし、こうして聞いて表にまとめてもらうことで、おおよそどのように考えられているのかを掴むことができた。
そして、自分の考えていた回答もそれほど実態と離れたものではないことがわかって、かなり安心した。

また、昨日の記事(SwiftUI時代のアーキテクチャ選定では「しょうきMVVMが最適」と書いたが、単に「MV」で良いとの指摘や、実際に「MV」を使っている企業も多いというのは、新しい発見であった。
記事を書くことで新たなフィードバックを得られるし、そのフィードバックをもとに新たな知識が身につくので、時間がある時にはmこうしてアウトプットに時間を使ってみたい。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?