2016年6月29日水曜日

Core Data を使用する(1)

Core Data は、以下のような機能を提供します。
  1. 変更の追跡機能。取り消し/再実行処理の支援。
  2. 変更の影響範囲の維持管理。
  3. オブジェクトの遅延読み込み、部分的な実体化によるオーバーヘッドの低減。
  4. 標準的な「キー値コーディング」検証メソッドを拡張したプロパティ値の自動検証。
  5. アプリのコントローラ階層との最適な統合による、UI同期の支援機能。
  6. データのグループ化、しぼり込み、組織化。
  7. 外部データリポジトリにデータを格納する処理の自動化。
  8. SQLを使わない複雑なクエリの生成。
  9. 楽観的ロック機構。
このフレームワークを使用することで、モデル階層の記述コード量を大幅に削減できます.
実際にサンプルアプリ(プロジェクト名: App)を作成して、Core Data の使い方を見ていきます。
開発/実行環境:Xcode8_beta, Swift3.0

エンティティとプロパティの生成

Xcode で、メニューバーから File > New > Project... を選択して新規プロジェクト(このデモでは Cocoa Application テンプレートを使用)を作成します。以下のように、プロジェクト作成時に
テンプレート選択ダイアログで「Use Core Data」をチェックします。

これにより、
Core Dataモデルのソースファイル App.xcdatamodeld(プロジェクト名.xcdatamodeld)が作成されます。

  • エンティティの生成
    自動生成された App.xcdatamodeld をナビゲータで選択して、Core Dataモデルエディタを表示します。

    1. 「Add Entity」をクリック。

      
ナビゲータ領域の「Entities」リストに新しい無題のエンティティが表示される。
    2. 新しい無題のエンティティを選択して、 Data Modelインスペクタで、エンティティ名、クラス名、必要なら親エンティティを入力してReturnを押します。
      ここで入力したクラス名(SyainMO)は、プログラムで参照するため識別しやすい名前にします。

      
 上の例のように親エンティティとして Jinbutu エンティティを指定する場合は、この Syain エンティティの定義前に Jinbutu エンティティを追加しておくことが必要です。
  • 属性と関係を生成
    1. 新規エンティティを選択して、生成先セクションの下部にあるプラス記号(+)をクリック。

      
新規の無題の属性または関係(総称して、プロパティと呼ぶ)が、
エディタ領域の「Attribute」セクションまたは「Relationship」セクションに追加される。 追加された属性や関係を選択して Delete キーを押せば削除できる。
    2. 追加プロパティを選択して、
Data Modelインスペクタの「Relationship」ペインまたは「Attribute」ペインで、プロパティの設定を行う。
      結果として、
属性または関係の情報がエディタ領域に表示される。プロパティ行で直接プロパティ名や型を修正することもできる。
  • エンティティ関連図(ER図)を表示
    上述のようにして、Jinbutu(人物:氏名,生年月日), Syain(社員:入社日), Busyo(部署:部署名) エンティティを作成して、属性と関係を追加。Syain は、Jinbutu を継承し、Syain : Busyo = 多 : 1 の関係です。
    モデルエディタの右下の Editor Style で ER図を選択。



Core Data スタック

プロジェクト作成時に「Use Core Data」をチェックすると、App.xcdatamodeld だけでなく、AppDelegate.swift ファイルに、Core Data スタックのコードが自動的に生成されます。スタックの主要な4つの要素と役割を以下に示します。
以下に示すコードは説明のため、自動生成されたコードのコメント文やメッセージを日本語に変更しています。
  • アプリのデータ保存用ディレクトリ:

    内容はコメントの通りです。(ファイル操作については次を参照:Swift 3.x:ファイル
    • 4行:lazy 指定により、このプロパティのコードは遅延実行される。
    • 11行:フォルダ名を"CoreDataDemo_Data"に変更。
      このデモアプリでは保存フォルダとして、
      "/Users/bri_tcho/Library/Application%20Support/CoreDataDemo_Data"
      を使用します。

  • 管理オブジェクトモデル:
    役割:モデルの構築。

    Core Data モデルの App.xcdatamodeld に対応します。
    開発者は、このオブジェクトを使って、定義したエンティティを操作することができます。
    • 7行:App.xcdatamodeld は実行時にコンパイルされて、App.momd として参照されます。
  • 永続ストアコーディネータ:
    役割:オブジェクトの永続化(永続化のファイル形式:SQLite, XML ファイル, メモリ, ..など)。

    管理オブジェクトモデル(エンティティ)の操作を実際の永続ストアに反映する。
    • 25-26行:アプリを初めて実行した場合、指定した保存フォルダは存在しないので、アプリドキュメントDIR + "/CoreDataDemo_Data"フォルダを作成。
    • 44行:コーディネータに25,26行で作成したフォルダ下の"CoreDataDemo.storedata"ファイルを永続ストアとして設定する。ファイル形式は XMLファイル。

  • 管理オブジェクトコンテキスト:
    役割:オブジェクトの管理。



データの永続化

自動生成された、その他のコードを見ながら、データの永続化がどのように行われるか見てみましょう。
まずはアプリを起動した後、なにもせずに終了(メニューで App > Quit App を選択)します。
AppDelegate.swift の以下の関数が実行されます:

  • 11-13行:Core Data の管理オブジェクトコンテキストに変更がないため、この条件判定が真となってアプリは終了します。
    ただし、managedObjectContext プロパティが参照された時点で、このプロパティを求めるコードが遅延実行されます。そのコード内では、persistentStoreCoordinator プロパティが参照され、同様にそのプロパティを求めるコードが遅延実行されます。その結果として、保存フォルダの "/Users/bri_tcho/Library/Application%20Support/CoreDataDemo_Data/"下に、空の"CoreDataDemo.storedata"ファイルが作成されます。
    プロパティについては次を参照:Swift 2.x: プロパティとメソッド

ここまで、3つのエンティティを Core Data モデルエディタで定義した以外にはほとんど何も行っていません。
上の関数を以下のように修正して、データの保存と、保存データの取得を行います。

  • 5-11:新しく追加したコード:
    • 7行:コンテキスト(managedObjectContext)から社員エンティ定義を取り出します。
    • 8行:その定義を元に社員エンティティ(SyainMOクラスのインスタンス)を生成して、コンテキスト(managedObjectContext)へ挿入します。
    • 9-11行:社員エンティティの各プロパティ(氏名、生年月日、入社日)に値を設定します。
  • 19行:コンテキストが変更されたので、この行が実行され、変更が保存されます。
  • 21-26行:新しく追加したコード:
    • 22行:フェッチ要求を生成します。特にフィルタ条件を設定していないので全件がフェッチ対象となります。
    • 23行:フェッチ要求を実行して、[SyainMO] 配列として結果を取得します。
    • 24-26:取得結果を表示します。

上記の修正を行った後、再度アプリを実行して、アプリメニューから App > Quit App を選択して、アプリを終了します。
"/Users/bri_tcho/Library/Application%20Support/CoreDataDemo_Data/CoreDataDemo.storedata"ファイルにデータが XMLとして保存されます。上記コードは社員データの新規追加なので、アプリを実行/終了するたびに、ファイルにはデータが追加されます。その結果、取得/表示データも増加します。

最後に

このデモアプリでは、以下の事を行いました。
  • モデルエディタでエンティティを追加して、属性と関係を設定する
  • 自動生成された Core Data スタックのコードの一部を変更してデータの永続化機能を調べる
次回のポスト「Core Data を使用する(2)」では、Core Data と UIとの連携や、より複雑なエンティティの定義などについて説明します。

0 件のコメント:

コメントを投稿