Core DataでNSFetchedResultsControllerDelegateを利用する

シェアする

Header

Core DataのクラスNSFetchedResultsControllerを使用すれば、テーブルビューで効率良くデータを表示することができます。

Core Dataのデータが変更されない場合は前回説明した方法で対応できますが、データが追加、更新、削除される場合は、NSFetchedResultsControllerDelegateのメソッドを使って、データの変更をテーブルビューに反映する必要がでてきます。

今回はNSFetchedResultsControllerDelegateを実装し、Core Dataに保存されたデータが変更された場合、テーブルビューの情報を正しく変更する方法を説明します。

サンプルプログラムの作成

.xcdatamodeldの作成

Xcodeを立ち上げ新規プロジェクトで「Single View Application」を選択します。プロジェクトの設定で「Use Core Data」のチェックを入れてプロジェクトを作成します。

Entity

.xcdatamodeldを選択し、新しくBookエンティティを追加します。publisher、titleという名前の属性を追加し両方の方をStringに変更、Optionalのチェックを外しておきます。

NSManagedObjectのサブクラスの作成

「File > New > File」を選択し「Core Data」から「NSManagedObject subclass」を選択します。先ほど作成した「Book」エンティティを選択すると以下の2つのファイルが作成されます。

ViewControllerの処理の作成

Main.storyboardにTable Viewをドロップして設置し、ViewController.swiftにControlドラッグしtableViewという名前でOutletを作成しします。またTable ViewのデータソースとしてViewControllerを指定しておきます。

まずソースコード全体を掲載します。

以下ポイントを説明します。

最初にdelegateの設定を行いNSFetchedResultsControllerDelegateの各メソッドが呼ばれるようにします。

NSFetchedResultsControllerDelegateの実装は以下の通りです。

全体の処理がtableView.beginUpdates/endUpdatesで囲まれているのはデータと画面表示の整合性がとれなくなるのを防ぐためです。

didChangeObjectがCore Dataのデータが変更されたときに呼ばれるメソッドで、変更の種類(Insert、Delete、Update、Move)に応じてテーブルの情報を変更しています。

セクションが存在する場合、セクション情報を追加、削除する処理も必要となります。

データの追加や更新は本来別の画面を作成しその画面とデータをやりとりして行うのが普通ですが、今回は説明のため画面下のツールバーボタンをタップした際、固定のデータを追加、更新、削除する処理としました。

実行結果

Add

▲「追加」ボタンをタップすると本のデータが1つ追加されます。

Update

▲「更新」ボタンをタップすると「早川書房」の書籍のタイトルに「★」が追加されました。

Delete

▲「削除」ボタンをタップすると「早川書房」の本が全て削除されました。

まとめ

NSFetchedResultsControllerDelegateに対応する方法を説明しました。

実コードの場合、例えば編集処理は、タップされた行のNSManagedObjectを編集画面に引き渡し、「完了」ボタンが押されたタイミングで一覧画面側の情報が書き換わることになります。NSManagedObjectContextが同じならばNSFetchedResultsControllerDelegateの処理を変更する必要は特にありません。

また削除処理ではテーブルビューのcommitEditingStyleでNSManagedObjectを削除するような処理になります。この場合もNSFetchedResultsControllerDelegate側の処理はこのまま利用することができます。