【Swift】Core Dataの使い方。編集データを外部ファイルに保存する。これを使えば大量データも怖くない。(Swift 2.1、XCode 7.2)

2020年6月16日

Core Dataとは

本記事ではSwiftで使える機能のCore Dataについて説明する。

Core Dataとは、アプリで入力または編集したデータを外部ファイルに保存する機能である。

過去の記事で説明したNSUserDefaultも外部ファイルに保存する機能だが、大量または複雑なデータを扱うにはCore Dataを使うのが適している。⇒「NSUserDefaultとは

データ保存の大まかなイメージを下図で説明すると、まずアプリで入力または編集したデータをオブジェクトとして管理オブジェクトコンテキストという入れ物に入れる。

一通り入れ終わったら、管理オブジェクトコンテキストに対して保存要求を行う。すると、オブジェクトの構造が定義されているモデルを使って形式が変換され、外部ファイルに出力される。これが保存の流れになる。

Core Dataの保存の流れ

 

逆の外部ファイルのデータを読み込む流れは、管理オブジェクトコンテキストに対してデータ取得要求を行うと、モデルを通して必要なデータのみが管理オブジェクトコンテキストに読み込まれ、それをアプリが参照する。

必要なデータの絞り込みをしっかりすれば、大量データが外部に保存されていてもメモリを逼迫することがないのがCore Dataの良いところだ。

Core Dataのデータ取得の流れ

 

Core Dataを使ってみる

Core Dataを使った簡単なプログラムを実装してみよう。

Core Dataを使うにはプロジェクトを作るときのオプション選択で「Use Core Data」にチェックを入れる。チェックを入れなくても使うことはできるが、チェックを入れると使うための下準備をしてくれる。

Core Dataを使おうとしている人でプロジェクトの作り方を知らない人はいないと思うが、念のためプロジェクトの作り方は次の記事を参照されたし。⇒「プロジェクトの作り方

Use Core Dataにチェックを入れる

 

下図は、「Use Core Data」のチェック有無で作られるファイルの違いを比較したもの。チェック有りの方は「プロジェクト名.xcdatamodeld」ファイルが最初から存在する。これは、先ほど説明したモデルを定義するためのファイルである。

その他の違いは、AppDelegate.swiftにCore Dataを使うためのプロパティとメソッドが追記されている。

Use Core Dataにチェックを入れた場合と入れなかった場合の比較

 

ラベル(下図赤枠)とテキストフィールド(青枠)をデバイス画面に配置する。黄緑枠のアシスタントエディタボタンを押してViewController.swiftを開く。

Ctrlキーを押しながらラベルをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。Connectionに「Outlet」、Nameに「testLabel」を入力して、Connectボタンを押す。

同じようにしてテキストフィールドの吹き出しの設定画面を表示させ、Connectionに「Outlet」、Nameに「testTextField」を入力して、Connectボタンを押す。これでラベルとテキストフィールドをソースコードから操作できるようになった。

ラベルとテキストフィールをデバイス画面に配置する

 

まずはCore Dataを使わない実装から。

ViewController.swiftを以下のコードに変更する。Returnキーを押すと、テキストフィールドに入力した文字列をラベルに追記するようにした。

 

以下は実際のプレイ動画。データの保存や読込みをしてないのでアプリを再起動するとラベルの文字列が初期値に戻る。

次はCore Dataを使う実装。モデルの定義から始める。

下図赤枠の「プロジェクト名.xcdatamodeld」を選択すると右側にモデルに定義されているエンティティが表示される。

エンティティとは、オブジェクトが持つプロパティや関係が記載されている定義書のことで、管理オブジェクトコンテキストに格納するオブジェクト1つにつき1つのエンティティが割り当たる。

Core Dataはモデルに記載されているエンティティを用いてオブジェクトから外部ファイルへ、外部ファイルからオブジェクトへの形式変換をしているのだ。

といってもまだエンティティを作っていないので、エンティティは何もない。

黄緑枠のAdd Entityボタンを押すと、紫枠のEntityが追加される。紫枠のEntityを選択、水色枠のデータモデルインスペクタボタンを押して設定画面を表示し、Nameに「Player」を入力する。これはソースコードからエンティティにアクセスするための識別子になる。

モデルを定義する

 

続けて、下図赤枠の「+」ボタンを押してAttributesの行を追加し、Attributeに「name」、Typeに「String」を入力する。もう一度赤枠の「+」ボタンを押して行を追加し、Attributeに「age」、Typeに「Integer 16」を入力する。

これでPlayerの持つ属性に名前と年齢が追加された。

エンティティに属性を追加

 

ViewController.swiftを以下のコードに変更する。

viewDidLoadメソッドで、管理オブジェクトコンテキストからすべてのPlayerエンティティを取得し、ラベルに名前を列挙している。

デリゲートメソッドの「Returnキー押下時の呼び出しメソッド」では、新しいPlayerエンティティを管理オブジェクトコンテキストに格納したあと、外部ファイルへの保存要求(saveメソッド)を行っている。

 

以下は実際のプレイ動画。Core Dataを使って保存したデータが再起動時にラベルに表示されるようになった。

 

次回以降もしばらくCore Dataの話を続ける。