Core Dataの利用
iPhone SDK 3.0以降ではデータの保存にCore Dataを使う事が出来ます。Core Dataを使ってデータを保存する事で得られるメリットは様々なものがあるため、 これから大量のデータを扱うアプリケーションを作る場合にはCore Dataの使用をまず検討した方が良いでしょう。
このCore Dataを使うためにはいろいろと新しく覚えなければならない事がありますが、はっきり言ってサンプルを見ているだけで理解するのは至難の業です。 初めてCore Dataに触れる人には、サンプルコードを見ても何をやっているのか分かりにくいのです。これはCore Dataの利点でもあるコード記述量の削減が、 逆にコードの個々の繋がりを分かりにくくしてしまっていることが原因でしょう。
そんな状態でいきなりiPhone Developer Centerに掲載されているサンプルを見ても、煙にまかれたようで全体像も把握できず、何が何だか分からないと思います。 そこで、まずはXcodeのテンプレートから作られる最も単純なCore Dataアプリケーションから、その動作を把握してゆくことにしましょう。 ここではiPhone SDK 3.1.2を使用しているものとして説明します。読者としては既にiPhoneでテーブルビューを使ったアプリケーション作成の経験はあるけれど、 Core Dataはこれまで全く使った事が無いという人を想定しています。テーブルビューを使ったiPhoneアプリケーション作成の経験が無い(もしくは経験が浅い)人は、 まずCore Dataの理解より先にテーブルビューを使ったiPhoneアプリケーションの基本的な作り方を理解するべきでしょう。
超簡易版サンプル?「FirstCoreData」
ではまず新規プロジェクトで「iPhone OS」>「Application」>「Navigation based Application」を選択し、 オプションの「Use Core Data for storage」にチェックを入れましょう。「選択」ボタンを押し、名前を入力します。 ここでは、「FirstCoreData」という名前にしたものとして説明を続けます。
ここでいきなりですがまず始めに「ビルドして進行」してみましょう。実機でもシミュレーターでもどちらでも構いません。 起動すると画面にはテーブルが表示されます。ナビゲーションバーの左に「Edit」、右に「+」と書かれたボタンが表示されます。 「+」を押すたびに現在の時刻がテーブルのセルに表示されてゆき、「Edit」を押して編集モードにすると項目の削除が出来ます。 機能としては実にシンプルですが、初めてCore Dataを勉強する場合にはうってつけの教材といえるでしょう。
xcdatamodelファイルによるデータモデルの定義
さて、このアプリケーションがどんな動作をするのか分かったところでコードを見てみましょう。Xcodeの左のリストでプロジェクトを展開してみます。 「Classes」はいままで同様にアプリケーションデリゲートと、表示を行うビューのコントローラーがあります。 「Resources」に「FirstCoreData.xcdatamodel」という名前の見慣れないファイルがあります。まずこのファイルをクリックして中を見てみましょう。 下の方に方眼紙のような部分があり、そこに「Event」というタイトルの角に丸みのある四角い枠が見えます。 中には「Attributes」と「Relationships」という項目があります。「Attributes」には「timeStamp」というものが入っています。 この「timeStamp」という項目は属性というもので、データ型は「日付」となっています。
先ほどアプリケーションを動かした際に、「+」ボタンを押した時に作られたのがこの「timeStamp」なのだろうということは容易に予測できます。 ここまでの部分をSQLite3データベースに当てはめてみると、この方眼紙全体が一つのデータベースファイルと置き換えられます。 「Event」と書いてある枠はエンティティと呼ばれるものですが、これはSQLite3で言うところのデータ行にあたるものです。 ただ、ここでの属性や関連の設定はテーブルのカラムを操作しているようなことにあたります。 属性「timeStamp」はテーブルの中に設定されたカラムにあたります。
アプリケーションのデリゲート
さて、次にアプリケーションのデリゲートのヘッダーファイル、「FirstCoreDataAppDelegate.h」を開いてみます。 ここには見慣れない3つの変数が見えます。まずNSManagedObjectModelですが、これは先ほど見た方眼紙の空間、つまりデータベースの構造を指すものです。 次にNSMangedObjectContextですが、これはデータベースファイル内のデータ全体の集合体と理解すれば良いでしょう。 そして最後のNSPersistentStoreCoodinatorですが、これがデータベースファイルへの入出力関係の処理をしていると理解すれば良いのではないでしょうか。
では具体的にメソッドファイル、「FirstCoreDataAppDelegate.m」で処理を追って行きましょう。まずスタート地点はおなじみのapplicationDidFinishLaunching:です。 ここでテーブルビューのコントローラーに先ほどのNSMangedObjectContextへのポインタを渡しています。 あとは今までなじみのある、ウインドウへのナビゲーションコントローラーのビューの追加をして、ウインドウを見えるようにしています。 つまり、アプリケーションデリゲートで押さえるべきはNSMangedObjectContextに関係する部分だけ、となります。
ここで気をつけるべきポイントは渡すポインタを「self.managedObjectContext」と表記している事です。 これにより、デリゲートのメソッドファイル内にあるmanagedObjectContextメソッドが呼ばれます。 これはすでにmanagedObjectContextがあればそれを返し、無ければ(nilならば)作成します。 これ以降も似たようにあればそれを返し、無ければ作成の繰り返しで進んでゆきます。
結局のところ何をしているかというと、アプリケーションのドキュメント用のフォルダに「FirstCoreData.sqlite」というファイルがあれば、 それとの間でデータの入出力ができるようにし、無ければファイルを新たに作成しています。新たに作成する場合には、 データの構造は「FirstCoreData.xcdatamodel」ファイルで定義したものとしています。 そしてそのファイルのデータ全体とそれにまつわる処理を行うオブジェクトのポインタをテーブルビューのコントローラーである「RootViewController」に渡しています。 実際のところ、自分でこれらのコードをカスタマイズする必要はありません。今後いろいろいじっていくにしても、これらの部分に手を加える必要はないでしょう。 テンプレートで作成してそのまま利用というスタンスで全く問題ないと思われます。
テーブルビューのコントローラー
では今度はテーブルビューコントローラーのヘッダファイル「RootViewController.h」を見てみます。こちらでも見慣れないものがあります。 NSFetchedResultsControllerはCore Dataのデータの集合体であるNSManagedObjectContextから、 テーブルビューにデータを表示するのに都合の良いようにデータを加工してくれる、Core Data形式のデータとテーブルビューとの橋渡しを行ってくれるものです。 ですから後はこのNSFetchedResultsControllerの振る舞いさえ分かれば、このアプリケーションの動きは理解したも同然となります。
そこで今度はメソッドファイル、「RootViewController.m」を見てみましょう。まずビューのXIBファイルが読み込まれた時点で、 ナビゲーションバーに2つのボタンが追加され、先ほどのコントローラーが作成されます。そしてフェッチが行われます。 このフェッチというのがSQLite3でのSQL文(ステートメント)の実行にあたるものです。メソッドファイルの下から1/3位のところにある、 fetchedResultsControllerメソッドを見てみましょう。これまでと同様に、既にあるならそれを返し、nilなら作成されるという流れです。 このコントローラーの作成に使っているのが、NSFetchRequestです。これにはNSEntityDescriptionと、 NSSortDescriptorを格納したNSArrayが組み込まれています。
順番にSQLite3に当てはめて説明すると、まず NSFetchRequestはSQL文に該当します。この中にいろいろと組み込むことで、実行できるSQL文になるわけです。 NSEntityDescriptionは検索を実行するテーブルを指すSQL文での「FROM ~」にあたる部分です。NSSortDescriptorは「SELECT ~」や「order ~」の部分にあたります。 今回の場合はソートは行わないため、全体として、SQL文での「SELECT timeStamp FROM Event」のようなものを作っていることになります。 そしてその実行結果が自動的にテーブルの行に格納されやすい状態になるという仕組みになっているわけです。 行の数やセクションの数はこのコントローラー関連の変数で設定されます。 セルの表示内容は、それぞれのセルに対応するオブジェクト(NSManagedObject)をfetchedResultsControllerのobjectAtIndexPath:メソッドで得た後、 表示に使うキー(属性)の値をキー値コーディングを使って取り出しています。
「+」のボタンが押された時の処理、insertNewObjectは全体でSQLite3での行の挿入に該当することを行っています。 まず新しい行にあたるオブジェクトをデータベース内に作ります。実際の挿入作業がNSManagedObjectで始まる行です。これでまず新しいオブジェクトを挿入します。 そして、そのオブジェクトの「timeStamp」というキーに現在の時刻という値をセットし、NSManagedObjectContextを保存しています。 オブジェクトへの値の設定は、キー値コーディングで行っています。この保存は即座にfetchedResultsController側で拾われ、勝手にビューが更新されます。
編集時の削除では、表示と同じくfetchedResultsControllerのobjectAtIndexPath: メソッドでセルに対応するオブジェクトを得て、 NSManagedObjectContextからdeleteObject:メソッドを使って削除を行っています。
なおアプリケーションの終了時には変更が行われて未保存なデータがあればそれをセーブしています。これも特に変更する必要は無いものです。
これでテンプレートから作られただけの「FirstCoreData」アプリケーションの説明は終わりです。 Core Dataは便利そうだけど何だかつかみどころが無くてよく分からないという人にとって、これが理解の第一歩になれば幸いです。
前へ次へ