本文およびサンプルコード修正のお知らせ
サンプル内の各クラスの役割を見直すという理由から、全体的にサンプルコードと解説を見直しました。(編集部 2018/11/19 12:45)
はじめに
連載第1回で触れた通り、Swiftではビューコントローラーの処理がUIに依存しがちであり、IBActionやdelegateの性質のためプログラムが長くなりがちです。RxSwiftを利用することで、UIへの依存を減らし、処理を明確にできることを前回までの連載で説明しました。今回は、そのプログラムの役割分担をクラス単位に広げ、MVVMモデルの導入の例について説明します。
MVVMモデルの導入
MVVMモデルとは、Model/View/ViewModelという3つの役割を持つクラスで構成されるシステムの考え方です。詳しくは連載第1回のページで確認してください。MVVMモデルとは、システムの考え方の1つであり、プログラムのルールではありません。そのため、開発者/開発チームの技術水準に応じて柔軟にシステムを構成してよいも言えます。
今回作成するサンプルもMVVMモデルで構成される例の1つであり、絶対的なものではありません。このことを忘れずに読み進めてください。
Wikipedia検索アプリにMVVMモデルを導入する
連載第3回で作成したWikipedia APIを使った検索アプリをベースに、簡易的なMVVMモデルを導入します。Wikipedia APIを使った検索アプリ自体の機能は、前回と同様です。
![Wikipedia APIを使った検索アプリ](http://cz-cdn.shoeisha.jp/static/images/article/11203/11203_001.png)
MVVMモデルの導入時に、Observer/Observable関連クラスを作成してWeb APIを利用した他のアプリでも利用できるようなサンプルを作成します。最初に処理の流れを図で整理しておきます。
![Observer/Observable関連クラスを利用したサンプルの処理の流れ](http://cz-cdn.shoeisha.jp/static/images/article/11203/11203_002_2.png)
- (1)ViewとViewModelのオブジェクトをbind
- (2)Wikipedia API 検索を実行する前に一定の制限を課してViewModelでの処理を実行
- (3)Wikipedia API検索を実行する際には、APIリクエストは汎用的に利用できる別クラスで行う
- (4)検索結果を解析してオブジェクトに格納
連載第3回のサンプルはオペレーターを使った処理の例でした。今回のサンプルは、RxSwiftとMVVMモデルを組み合わせる例なので、次の3つの観点からプログラムを組んでいきます。
実装する内容 | 該当部分 |
---|---|
検索キーワード/検索結果をViewModelのオブジェクトとbind | View |
Wikipedia API検索をObserveパターンを利用して行う | ViewModel |
Wikipedia API検索を行うクラスを汎用的に作成する | MVVM以外 |
この3点を念頭に置いて、MVVMモデルを導入したクラスを設計していきます。
MVVMモデルを導入する際のクラスを設計する
前項で述べた観点から、作成するクラスはMVVMモデルの3クラスとWikipedia APIへHTTPリクエストを行う1クラスの合計4クラスとします。作成するクラスは次の通りです。
役割 | クラス/構造体名 | 概要 |
---|---|---|
Model | WikipediaSearchAPIModel | 検索結果を生成 |
View | WikipediaSearchAPIViewController | 検索バー、テーブルを表示 |
ViewModel | WikipediaSearchAPIViewModel | 検索バーからの値の受け取り/Wikipedia API検索/検索結果の返却 |
Wikipedia API呼び出し | WikipediaAPIClient | Wikipwdia APIへのHTTPリクエスト |
ViewはSwiftで言う一般的なビューではなく、ビューコントローラーのクラスで担当します。サンプルでは、MVVMモデルの各役割を明確にするために、View以外ではUIKitフレームワークをimportしないことを最低限のルールとします。
Wikipwdia APIへのHTTPリクエストを別のクラスに分けます。View-ViewModel間の変数のやり取りにはデータバインドを用います。ViewModelの処理はViewから直接呼ぶのではなく、onNextイベント発生時に呼ばれるように前もって定義します。