MVVMモデルをもっと便利に使ってみよう(前編)~入力/出力の変数に注目したMVVMモデルの設計
RxSwiftで一歩進んだiOSアプリ開発 第5回
ダウンロード サンプルファイル (606.7 KB)
連載第5回では、連載第4回で説明したMVVMモデルに対してもう少し踏み込んだ使い方を説明します。MVVMモデルのさらに踏み込んだ使い方や代表的なライブラリの使い方などを、前編と後編の2回に分けて説明します。今回は前編です。本連載では、これからRxSwiftを導入する方を対象読者としている関係上、RxSwift導入の初歩的な手順に関して主な説明を行います。そのため、便宜上クラス/メソッドの使い方が必ずしもRxSwiftの詳細な仕様通りでないこともあります。この点をご了承ください。
はじめに
連載第3~4回にかけてRxSwiftで処理を簡潔に記述できること、MVVMモデルを導入することにより機能を分離してクラスを管理できることなど、RxSwiftを利用した、基本的な画面の作成方法について主に紹介しました。今回はもう少し深くクラス分けについての考察を行い、もっと便利に利用できる方法などについて説明します。
MVVMモデルをもっとわかりやすく便利に利用する
RxSwiftはRxが本来持っている性質とともに、Observer/Observable関連クラスも充実しています。このことは、言い換えるとアプリのどの場面でも同じ仕様のクラスが同じように使えてしまうという意味です。スマートフォンアプリの画面の表示には、必ずと言っていいほどタッチなどの動作を含めた入力と画面への表示としての出力を伴います。今回はこの入出力に注目してRxSwift/MVVMモデルの導入を考えてみます。
RxSwiftでの入出力の扱いについて
連載第4回のサンプルのWikipedia検索アプリでは、検索ワード(searchWord: Variable<String>)と検索結果のリスト(items: Variable<[Result]>)はViewModel内で並列に定義されていました。2つの変数は一見したところでは、入力のための変数なのか、出力のための変数なのか区別はつきません。処理内容までソースコードを追って初めて、どういう目的の変数かわかります。
RxSwiftは、書き方も容易で導入がしやすいライブラリです。その反面、さまざまな処理で利用できるため、似たような変数や処理が並んでしまうとかえって扱いに困ることもあります。
その解決方法の1つとして、連載第4回で紹介した、Swiftのプロトコルの使い方を利用してRxSwiftの入出力をわかりやすくできる方法があります。
入出力変数をプロトコルで管理する
入出力の変数を区別するために、ViewModelのクラスを作成する際に変数をプロトコルで分けて定義するという方法があります。ViewからViewModelのプロパティを利用する際には、入力なのか出力なのかが分かるようにする方法です。
検索ワード(searchWord: Variable<String>)を入力、検索結果のリスト(items: Variable<[Result]>)を出力の変数としてプロトコルで定義する例は次のようになります。
protocol ViewModelInputs {
var searchWord: Variable<String?> { get }
}
protocol ViewModelOutputs {
var items: Observable<[Img]> { get }
}
2つの変数を { get } で読み込み専用と定義しているのは、「プロトコルを実装するクラスの初期化処理でデータバインドを行い、クラスの外からの参照を読み込みのみで行う」といった意味です。ただしSwiftの仕様では、プロトコルの実装の際に変数の読み込みができていれば、値を書き込み、「var」を「let」で扱うことも許可されています。この辺りのSwiftの仕様はあまり厳密ではありません。
入出力のプロトコルを定義した後は、入出力のプロトコル自体にプロパティでアクセスできるプロトコルを次のように定義します。
protocol ViewModelType {
var inputs: ViewModelInputs { get }
var outputs: ViewModelOutputs { get }
}
上記のプロトコルを実装したクラスでは、入力用の検索ワードにはinputs.searchWordプロパティで、出力用の検索結果のリストにはoutputs.itemsプロパティでアクセスすることができます。具体的な例は次の通りです。
class ViewModel: ViewModelInputs, ViewModelOutputs, ViewModelType {
// MARK: - Properties
var inputs: ViewModelInputs { return self }
var outputs: ViewModelOutputs { return self }
// Input Sources
let searchWord = Variable<String?>(nil)
// Output Sources
let items: Observable<[Result]>
# 後略
クラスの外からは、inputs/outputsを変数の前につけることで入出力を区別して変数にアクセスできます。クラスの内部では、inputs/outputsをつけずに変数を利用することができます。このようにプロトコルを利用することで、入出力の変数を区別して扱うことができます。
この記事は参考になりましたか?
- RxSwiftで一歩進んだiOSアプリ開発連載記事一覧
-
- MVVMモデルをもっと便利に使ってみよう(後編)~ViewModelの変数と具体的な処理方...
- MVVMモデルをもっと便利に使ってみよう(前編)~入力/出力の変数に注目したMVVMモデル...
- RxSwiftの仕組みを利用して、MVVMモデルを導入しよう
- この記事の著者
-
WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
