【Swift】Core Dataの使い方。エンティティごとに出力先の外部ファイルを変える。(Swift 2.1、XCode 7.2)

2020年6月16日

CONFIGURATIONSとは

本記事では、データモデルの「CONFIGURATIONS(以下、コンフィグレーション)」について説明する。

コンフィグレーションとは、外部ファイルに出力するエンティティをまとめた定義のことである。デフォルトでは1つのコンフィグレーションの中に、すべてのエンティティが記載されている。

なので、前回記事までは、Core Dataを使ってデータを保存するときの出力先の外部ファイル(.sqlite)は1個である。

データ保存の出力先ファイルが1つ

 

コンフィグレーションを増やしてエンティティを振り分けると、エンティティごとに出力先の外部ファイルを変えられるようになる。

出力先の外部ファイルを2つに分ける例

 

コンフィグレーションの追加を試す

実際にコンフィグレーションを追加して、出力先の外部ファイル(.sqlite)をエンティティごとに分けてみよう。

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

生徒と教師のデータをCoreDataを使って外部ファイルに保存するものを実装しておいた。この段階では出力先の外部ファイルはまだ1つである。

以下は検証用プロジェクトのViewController.swiftのソースコード。アプリ起動時に、外部ファイルの出力先フォルダパスをデバックエリアに表示している。

 

デフォルトのコンフィグレーションを使った場合

まず、プレイ動画で保存した生徒「田中、女性」と教師「佐野、数学」の外部ファイルを確認し、デフォルトのコンフィグレーション(外部ファイルが1個)の場合、どのように保存されるのかを確かめる。

Xcodeのデバッグエリアに表示されている外部ファイルのフォルダパスをコピーする。

外部ファイルの出力先フォルダをコピーする

 

Macの「LaunchPad」⇒「その他」からターミナルを起動する。

ターミナルを起動する

 

ターミナル画面で「cd フォルダパス」を叩いて、外部ファイルの場所まで移動する。続いて、lsコマンドを叩くと、出力された外部ファイル(.sqlite)が1つ見つかる。

 

「sqlite3 外部ファイル名」を叩いてsqlite3を起動する。sqlite3とは、SQLiteデータベースの内容を確認編集するためのコナンドラインユーティリティーのことで、最近のMacには標準インストールされている。

「.tables」を叩いて保存されているテーブルの一覧を表示する。ZSTUDENTが生徒テーブル、ZTEACHERが教師テーブルである。

 

「select * from ZSTUDENT;」を叩いてテーブルの中身を表示する。登録した生徒「田中」が表示された。

データが見づらいので表示を変更しよう。

「.header on」を叩いて、テーブルの列名が表示されるようにする。

「.mode column」を叩いて、列の幅が見やすいように調整されるようにする。

そして、再度「select * from ZSTUDENT;」を叩くと以下のように見やすい表示になる。

 

見慣れない列があるので各列の意味を参考までに説明しておく。

「Z_PK」はプライマリキーのことで、データを追加するごとに1から順番に番号が振られる。

「Z_ENT」はテーブルごとに振られる連番で、同一テーブル内のZ_ENTはすべて同じ数字になる。

「Z_OPT」はレコードの更新回数のことで、レコードが更新される度に数字が1増加していく。

ZSEXは性別、ZNAMEは名前の列である。

 

教師のテーブルを確認する。「select * from XTEACHER;」を叩くと教師「佐野、数学」が登録されていることが分かる。

 

2つのコンフィグレーションを使った場合

上記の作業により、1つの外部ファイルの中に、生徒と教師のデータが保存されていることが確認された。

次に、生徒用と教師用の2つのコンフィグレーションを作り、出力先の外部ファイルを2つに分ける。

下図赤枠の「プロジェクト名.xcdatamodeld」を選択、黄緑枠の「+」ボタンを長押しして吹き出しのメニューを表示し、「Add Configuration」を選択する。これを2回行う。

コンフィグレーションを追加する

 

すると、下図赤枠枠にコンフィグレーションが2つ追加されるので、1つずつダブルクリックして編集状態にし、名前を「StudentConfig」と「TeacherConfig」にする。

StudentConfigを選択し、黄緑枠のStudentエンティティをコンフィグレーションの定義にドラッグ&ドロップで入れる。Teacherエンティティも同じようにしてTeacherConfigに入れる。これで、生徒用と教師用の2つのコンフィグレーションができた。

ちなみに、Defaultのコンフィグレーションはもう使わないので消したいところだが、消すことはできない。

コンフィグレーションにエンティティを追加する

 

AppDelegate.swiftのpersistentStoreCoordinateorプロパティを以下に変更する。

生徒用と教師用の出力先URLを定義したのと、コーディネーターに生徒用と教師用の永続ストアを追加した(青色箇所)。

 

出力先外部ファイルが変わって過去の外部ファイルを残しておくのは紛らわしいので、アプリを一旦削除してからシュミレーターを実行しよう。

ちなみに、アプリを削除する方法は、以下の動画のようにアイコンを長押しして×ボタン。

 

以下は実際のプレイ動画

 

先ほどと同じ手順で外部ファイルを見に行くと。。。外部ファイル(.sqlite)が2つに増えた。

 

生徒用の外部ファイル(StudentCoreData.sqlite)の中身を確認すると、生徒用と教師用の両方のテーブルがあるが、データは生徒テーブルのみが持っていることが分かる。

 

教師用の外部ファイル(TeacherCoreData.sqlite)の中身を確認すると、こちらにも生徒用と教師用の両方のテーブルがあるが、データは教師テーブルのみが持っていることが分かる。

 

以上、コンフィグレーションを増やしてエンティティごとの出力先を分ける方法を説明した。

1つ注意点があり、異なるコンフィグレーションのオブジェクト同士はリレーションシップを追加できないということだ。なので、将来的なエンティティ間のリレーション追加も考慮してコンフィグレーション分けの有無を判断するべし。

コンフィグレーション分けがどれだけ性能アップに寄与するのかも気になるところなので今後の課題とする。