初めてのCore Data on iPhone(Xcode 4.5.1対応)

Konton's iPhone application labolatory

English top page

Core Dataの利用

iPhone SDK 3.0以降ではデータの保存にCore Dataを使う事が出来ます。Core Dataを使ってデータを保存する事で得られるメリットは様々なものがあるため、 これから大量のデータを扱うアプリケーションを作る場合にはCore Dataの使用をまず検討した方が良いでしょう。

このCore Dataを使うためにはいろいろと新しく覚えなければならない事がありますが、はっきり言ってサンプルを見ているだけで理解するのは至難の業です。 初めてCore Dataに触れる人には、サンプルコードを見ても何をやっているのか分かりにくいのです。これはCore Dataの利点でもあるコード記述量の削減が、 逆にコードの個々の繋がりを分かりにくくしてしまっていることが原因でしょう。

そんな状態でいきなりiPhone Developer Centerに掲載されているサンプルを見ても、煙にまかれたようで全体像も把握できず、何が何だか分からないと思います。 そこで、まずはXcodeのテンプレートから作られる最も単純なCore Dataアプリケーションから、その動作を把握してゆくことにしましょう。 ここではXcode 4.5.1を使用しているものとして説明します。読者としては既にiPhoneでテーブルビューを使ったアプリケーション作成の経験はあるけれど、 Core Dataはこれまで全く使った事が無いという人を想定しています。テーブルビューを使ったiPhoneアプリケーション作成の経験が無い(もしくは経験が浅い)人は、 まずCore Dataの理解より先にテーブルビューを使ったiPhoneアプリケーションの基本的な作り方を理解するべきでしょう。


超簡易版サンプル?「FirstCoreData」

Xcpdeを起動すると、設定変更をしていなければ「Welcome to Xcode」と書かれた画面が開きます。 すぐ下に「Create a new Xcode project」という項目があるので、それをクリックします。 テンプレートの選択画面になるので、「iOS」>「Application」>「Master-Detail Application」を選択し、「Next」を押します。 ここでは「Product Name」を「FirstCoreData」という名前にしたものとして説明を続けます。 今回は簡単にするため、DevicesはiPhoneを選択してください。 オプションの「Use Storyboards」「Use Core Data」「Use Automatic Reference Counting」のそれぞれにチェックが入っているか確認しましょう。 「Next」ボタンを押し、名前を入力します。 最後に保存場所を決定します。保存場所にこだわりがなければそのまま「Create」を押します。

ここでいきなりですがまず始めにビルドして進行してみましょう。実機でもシミュレーターでもどちらでも構いません。 画面の左上にオーディオやビデオの再生ボタンのようなアイコンのボタンがあると思いますので、それを押してみてください。 その右側に「FirstCoreData > iPhone 6.0 Simulator」などという表示が確認出来ると思います。 「iPhone 6.0 Simulator」などと表示されている部分をクリックすると、ポップアップが出て実行する対象を選ぶ事が出来ます。 起動すると画面にはMasterというタイトルが書かれたナビゲーションバーとテーブルが表示されます。 ナビゲーションバーの左に「Edit」、右に「+」と書かれたボタンが表示されます。 「+」を押すたびに現在の時刻がテーブルのセルに表示されてゆき、「Edit」を押して編集モードにすると項目の削除が出来ます。 機能としては実にシンプルですが、初めてCore Dataを勉強する場合にはうってつけの教材といえるでしょう。


xcdatamodelファイルによるデータモデルの定義

さて、このアプリケーションがどんな動作をするのか分かったところでコードを見てみましょう。 先ほど再生ボタンのようと書いたボタンの右側に停止ボタンのようなボタンがありますので、それを押してください。 これでシミュレーターか実機で実行中だったプログラムが停止します。 次にXcodeの左のリストでプロジェクトを見てみましょう。 一番上に「FirstCoreData」と書かれた青いアイコンのあるものがあります。 その下に「FirstCoreData」というグループがあり、中が展開されています。 そこにはアプリケーションデリゲートと、表示を行うビューのコントローラーなどがあります。 その中に「FirstCoreData.xcdatamodel」という名前の見慣れないファイルがあります。まずこのファイルをクリックして中を見てみましょう。 「ENTITIES」にある「Event」というものが選択された状態になっていて、「Attributes」や「Relationships」などという項目があります。 「Attributes」には「timeStamp」というものが入っています。 この「timeStamp」という項目はAttributeというもので、Typeは「Date」となっています。

先ほどアプリケーションを動かした際に、「+」ボタンを押した時に作られたのがこの「timeStamp」なのだろうということは容易に予測できます。 ここまでの部分をSQLite3データベースに当てはめてみると、このファイル全体が一つのデータベースファイルと置き換えられます。 「Event」と書いてある枠はエンティティと呼ばれるものですが、これはSQLite3で言うところのテーブルにあたるものです。 属性や関連の設定はテーブルのカラムを操作しているようなことにあたります。 属性「timeStamp」はテーブルの中に設定されたカラムにあたります。


アプリケーションのデリゲート

さて、次にアプリケーションのデリゲートのヘッダーファイル、「AppDelegate.h」を開いてみます。 ここには見慣れない3つの変数が見えます。まずNSManagedObjectModelですが、これは先ほどのデータベースの構造を指すものです。 次にNSMangedObjectContextですが、これはデータベースファイル内のデータ全体の集合体とでも理解すれば良いでしょう。 そして最後のNSPersistentStoreCoodinatorですが、これがデータベースファイルへの入出力関係の処理をしているものと理解すれば良いのではないでしょうか。

では具体的にメソッドファイル、「AppDelegate.m」で処理を追って行きましょう。まずスタート地点はおなじみのapplication:DidFinishLaunchingWithOptions:です。 ここでテーブルビューのコントローラー(MasterViewController)に先ほどのNSMangedObjectContextへのポインタを渡しています。 アプリケーションデリゲートで押さえるべきはNSMangedObjectContextに関係する部分だけ、となります。

ここで気をつけるべきポイントは渡すポインタを「self.managedObjectContext」と表記している事です。 これにより、デリゲートのメソッドファイル内にあるmanagedObjectContextメソッドが呼ばれます。 (より正確に言えば、managedObjectContextメッセージを送信して、その最終結果として上記メソッドが呼ばれています。) このメソッドはすでにmanagedObjectContextがあればそれを返し、無ければ(nilならば)作成します。 これ以降も似たようにあればそれを返し、無ければ作成の繰り返しで進んでゆきます。

結局のところ何をしているかというと、アプリケーションのドキュメント用のフォルダに「FirstCoreData.sqlite」というファイルがあれば、 それとの間でデータの入出力ができるようにし、無ければファイルを新たに作成しています。新たに作成する場合には、 データの構造は「FirstCoreData.xcdatamodel」ファイルで定義したものとしています。 そしてそのファイルのデータ全体とそれにまつわる処理を行うオブジェクトのポインタをテーブルビューのコントローラーである「RootViewController」に渡しています。 実際のところ、自分でこれらのコードをカスタマイズする必要はありません。今後いろいろいじっていくにしても、これらの部分に手を加える必要はないでしょう。 iCloudでデータベースを同期させるなら手を加える必要もあるのですが、ここではそれについては扱いません。 とりあえずテンプレートで作成して、そのまま利用するというスタンスで全く問題ないと思われます。


テーブルビューのコントローラー

では今度はテーブルビューコントローラーのヘッダファイル「MasterViewController.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」というキーに現在の時刻という値([NSdate date])をセットし、NSManagedObjectContextの変更を保存しています。 オブジェクトへの値の設定は、キー値コーディングで行っています。この保存は即座にfetchedResultsController側で拾われ、勝手にビューが更新されます。

編集時の削除では、表示と同じくfetchedResultsControllerのobjectAtIndexPath: メソッドでセルに対応するオブジェクトを得て、 NSManagedObjectContextからdeleteObject:メソッドを使って削除を行っています。

なおアプリケーションの終了時には変更が行われて未保存なデータがあればそれをセーブしています。これも特に変更する必要は無いものです。

これでテンプレートから作られただけの「FirstCoreData」アプリケーションの説明は終わりです。 Core Dataは便利そうだけど何だかつかみどころが無くてよく分からないという人にとって、これが理解の第一歩になれば幸いです。

前へ次へ
Copyright© 2009 Konton All rights reserved. - このサイトについて - サイトマップ

Valid XHTML 1.1 正当なCSSです!