[SwiftUI][CoreData] SwiftUI と MVVM で始める CoreData 入門 (その3:1回目のリファクタリング と ViewModel の作成)

SwiftUI と CoreData を組み合わせたアプリの作り方を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Catalina 10.15.7
  • Xcode 12.2
  • iOS 14.2

いろいろと、コードを書いてきたので、一度 リファクタリング します。

ここまでの Model コード

MyTODOModel.swift

気になる点は、「TODOItemStore で TODOItem の配列を保持しておく必要はあるか?」です。

パフォーマンス上の問題が出るまでは、必要な時に、CoreData から fetch するようにしてみます。

こうすることで、TODOItemStore が保持している [TODOItem] と CoreData の保持している CDTODOItem の整合性を考える必要がなくなります。

なんとなく [TODOItem] を保持しておいて、@Published 指定すると、変更に対して 自動更新が起こりそうですが、Model 内部で持っている配列が変更されても、更新はされないです。

ということで、TODOItemStore は TODOItem を保持せず、リクエストに応じて、CoreData から fetch したものをベースに、TODOItem の配列を返すとしました。

MyTODOModel

ViewModel の作成

ViewModel は、ObseravableObject に準拠し、Model である TODOItemStore を保持するようにします。

MyTODOViewModel

TODOItem の配列も、@Published 指定で保持するようになると思いますが、必要になったら実装することにします。

App, View 実装前のクリーンアップ

App と View には、テンプレートコードが残っているので、ViewModel や View の実装を進める前にきれいにしておきます。

App のクリーンアップ

MyTODOApp.swift
コード解説
  1. App と同じライフサイクルを持つように、ViewModel を生成します。
  2. EnvironmentObject に登録し、すべての下位ビューから参照できるようにします

Persistence は使用しませんので、ファイルを削除して構いません。

View のクリーンアップ

ContentView は、以下のように修正しました。

  • EnvironmentObject として、 ViewModel を参照します
  • fetch 等の CoreData を直接操作する箇所を削除しました
  • テンプレートで用意されているリストの追加・削除は、そのまま使えそうですので、ダミーのデータ(String) を用意して残しています。
ContentView.swift code

View, ViewModel 共に、実装を開始できる状態になったので、次回は、UITest, View, ViewModel を実装していきます。

テストを忘れずに

コードを変更したら、テストが通ることを確認します。

Model のコードを変えたのでそこに合わせるためにテストコードの修正も必要となりました。

Model_Tests code

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です