【Swift】Core Dataの使い方。Relationshipを使った具体的な実装方法(Swift 2.1、XCode 7.2)

2020年6月16日

Relationshipの説明の続き

前回記事ではRelationship(以下、リレーションシップ)の基本的な考え方について説明した。⇒「前回記事

本記事はその続きで、リレーションシップの具体的な実装方法を説明する。

前回記事で用いた生徒一覧から部活一覧を参照して部員一覧を表示するものを実装する。また、生徒を削除すると部員一覧からも消えるようにする。

■生徒一覧
生徒表

 

■部活一覧
部一覧

 

以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる人はご利用されたし。
⇒「テスト用プロジェクト

事前準備では、生徒一覧をテーブルビューに表示し、左スワイプから削除できるようにしておいた。生徒エンティティと部活エンティティのモデルは定義済みである。

 

以下はStudentTableViewController.swiftの変更前のソースコード。

リレーションシップを追加する

まずは、生徒エンティティと部活エンティティにリレーションシップを追加する。

下図赤枠の「プロジェクト名.xcdatamodeld」を選択、黄緑枠のStudentエンティティを選択、紫枠の「+」ボタンを押してRelationshipの行を追加する。

入力項目のRelationshipに「club」、Destinationに「Club」を入力する。これで、生徒エンティティから部活エンティティへのリレーションシップが追加された。

StudentエンティティにRelationshipを追加する。

 

続いて、下図水色枠のClubエンティティを選択、紫枠の「+」ボタンを押してRelationshipの行を追加する。

入力項目のRelationshipに「student」、Destinationに「Student」、Inverseに「club」を入力する。これで、部活エンティティから生徒エンティティへのリレーションシップが追加された。

黄緑枠のデータモデルインスペクタボタンを押して設定画面を表示し、Typeに「To Many」を設定する。これは、前回記事で説明した「1対多」の設定である。

赤枠のStudentを再度選択して先ほど追加したリレーションシップを見ると、Inverseに「student」が自動で設定されているはずである。Inverseは逆関係を設定する項目である。つまり、clubとstudentの双方向のリレーションシップが確立されたということだ。

Clubのリレーションを追加する

 

エンティティのサブクラスを作る

下図赤枠の「プロジェクト名.xcdatamodeld」を選択したあと、メニュー⇒「Editor」⇒「Create NSManagedObject Subclass」とたどる。

エンティティのサブクラスを作成する

 

データモデルの一覧が表示されるので、「プロジェクト名」にチェックが入っていることを確認して「Next」ボタンを押す。

データモデルを選択する

 

データモデルに定義されているEntityの一覧が表示されるので、StudentとClubの両方にチェックを入れて「Next」ボタンを押す。

StudentとClubのエンティティを選択する

 

保存先を指定する画面が表示されるので、プロジェクトのフォルダが指定されていることを確認して「Create」ボタンを押す。

保存先を指定する

 

上記の結果、「Student+CoreDataProperties.swift」と「Club+CoreDataProperties.swift」の2つのファイルが上書きされる。

「Student+CoreDataProperties.swift」は以下のコードになる。部活オブジェクトを設定するためのclubプロパティが追加されている。

 

「Club+CoreDataProperties.swift」は以下のコードになる。複数の生徒オブジジェクトを設定するためのNSSet型のstudentプロパティが追加されている。

 

リレーションのプロパティを利用して実装する

StudentTableViewController.swiftの「検証用データを保存するメソッド」を以下のコードに変更する。

生徒の検証用データを保存するときに、部活のオブジェクトを取得してclubプロパティに設定するようにした。

 

StudentTableViewController.swiftの「データを返すメソッド」を以下のコードに変更する。

セルのラベルに所属部の名前を表示するようにした。

 

ここまでで実行すると、以下の動画のようになる。エラーが出た人は次の記事を確認されたし。⇒「データ不整合によるエラー

 

逆関係を利用して部員一覧を表示する

次に、ナビゲーションバーにある「部活一覧へ」ボタンを押すと、部活ごとの部員一覧が表示されるようにする。

ClubTableViewController.swfitを以下のコードに変更する。

「データを返すメソッド」で、逆関係のstudentプロパティから所属部員のオブジェクトを取り出して、ラベルに設定している。

 

気がついたかも知れないが、部活エンティティのstudentプロパティ(NSSet型)に値を設定するコードはどこにもないにも関わらず、「データを返すメソッド」でstudentプロパティから生徒のオブジェクトを取り出して使っている。

これは、最初の画面で生徒オブジェクトのclubプロパティに部活オブジェクトを設定するときに、逆関係のstudentプロパティに自動で生徒オブジェクトが追加されるためである。

しかも、生徒オブジェクトを削除すると、studentプロパティの参照も自動で消してくれるのでclubとstudentの整合性を気にする必要がない(設定によっては自動で消さないようにもできる)。

逆関係の定義は必須ではないが、あると役に立つことが多いので作っておきたい存在だ。逆関係便利なり。

以下は実際のプレイ動画