スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

インデックス作成ツール/Core DataとCocoa Bindingの仕組み(その1)

 とりあえずプログラムを動かすところまで進んだので、少し仕組みについて説明しよう。この部分は知らなくてもある程度までは作れてしまうんだけど、やっぱりどうしてそうなっているのかを知っておいた方が良いだろう。
 OSXでプログラムを動かす仕組みはいくつかあるのだが、今回使ったのはAppleがCocoaと呼んでいる仕組みだ。Cocoaではいろいろな部品を、まるでレゴや電子ブロックのように繋ぎ合わせてプログラムを作っていく。今まで作ってきたプログラムでもNSTableViewやNSTextFieldといったレイアウト上の部品や、AlbumControllerといった部品を使ってきた。これらの部品はオブジェクトと呼ばれている。オブジェクトには、テーブルやボタン、テキストフィールドのように、プログラムを動かす時に眼に見えるものもあるし、AlbumControllerのようにプログラムの中にあっても画面には出てこないものもある。
 実は、AlbumエンティティやSongエンティティも画面には出てこないが一つのオブジェクト(部品)なんだ。もう一度、データモデリングの時に使った画面を思い出してみて欲しい。

 このエンティティ編集の画面の右側に書かれていた、NSManagedObjectというのが(NSTableViewやNSTextFieldと同じく)部品の種類を表している。エンティティの属性や、関係を決めていく作業というのは、実は、テーブルのカラム数や、ボタンに描かれる文字などをInterface Builderで決めているのと同じように、プログラムで使う部品(オブジェクト)をどんなものにするか、という設定であったわけだ。

 しかし、エンティティオブジェクトには、レイアウトウィンドウにあったテーブルやボタンとは違う特徴を一つ持っている。ウィンドウに配置されたオブジェクトというのは、プログラムが動き始めて、ウィンドウが表示された時に自動的に作られ、ウィンドウが消える時に消される。しかし、エンティティオブジェクトはユーザーが「+」ボタンをクリックした時に作られ、「ー」ボタンが押された時に消される。また、メニューを使ってファイルに保存したり、ファイルから読み込んだりすることも出来る。さらに、プロパティの内容を編集したり、編集の取り消しややり直しをしたりすることも出来る。
 このような動きを可能にするために、エンティティオブジェクトという部品を作ったり削除したり編集するための部品(=オブジェクト)がある。それがNSManagedObjectContextという種類のオブジェクトだ。Cocoa Bindingを行う時に、最初にAlbumControllerに対してBindを行ったのが、managedObjectContextだったことを覚えているだろうか? これがそのオブジェクトだったわけだ。

 次回は、実際これらのオブジェクト達の間でなにが起きているのかを説明しよう。
スポンサーサイト

インデックス作成ツール/ユーザーインターフェース(その3)

 ここからは、Cocoa Bindingを使ってエンティティと入力画面を接続する。

 まずは、パレットからCocoa ControllersのNSArrayControllerを選び、ドキュメントウィンドウ(レイアウトウィンドウではない!)にドラッグ&ドロップする。


 ドラッグしたら、名前のところをダブルクリックして、名前を”AlbumController"に変更する。さらにインスペクタのAttributeでMode:をEntityにしEntity NameにAlbumを入力する。

 続いて、インスペクタをBindingsに切り替えて、ParametersのmanagedObjectContextを指定する。頭の三角をクリックすると、詳細設定が現れるので、Bind to:にFile's OwnerをModel key pathにmanagedObjectContextを選ぶ。同時に右上のBind欄にチェックが入るはずだ。もし入っていないようであればチェックを入れておこう。これで、データモデリングで作成したAlbumエンティティと、今ドキュメントウィンドウに入れたAlbumControllerとの間の接続が終わったことになる。

 次はレイアウト画面上に置いた部品と、今作ったAlbumControllerとを接続する。最初はTableViewのTitleカラムを選ぶ。一旦テーブルをダブルクリックしてからTitle欄をクリックしよう。これで、カラムが選ばれた状態になるので、インスペクタのBindingsで接続の設定を行う。Valueの中にあるvalueの頭の三角をクリックしてBind to:にAlbumControllerをController Key:にarrenged Objectsを、Model Key Path:にtitleを設定する。Model Key Pathではリストから選べないかもしれないが、かまわずキーボードからタイプする。

 それが終わったら、今度は右側だ。タイトルを入力するTextFieldをクリックして同じようにValusにBindingを設定する。さっきの指定とだいたい一緒だが、Controller Key:には今度はselectionを選ぶ。TableViewの時には一覧を表示するためにarrenged Objectsを選んでいたのだが、今度はテーブルで選ばれた一つだけを対象にしたいからselectionを選ぶわけだ。
 Artist,Relese Date,ReviewについてもTitleと同じようBindingの設定を行う。Model Key Path:にそれぞれartist,releaseDate,reviewを指定する。これでAlbumエンティティの属性が画面上の部品と結びつき、編集や表示が出来るようになる。

 ここまで終わったら、今度は追加と削除のボタンの設定を行う。Controlキーを押しながら「+」ボタンをクリックしてマウスをドラッグすると、ボタンから線が伸びてくるので、この線をドキュメントウィンドウにあるAlbumControllerに接続してマウスボタンを離す。インスペクタウィンドウはConnectionsに変わり、Action in AlbumControllerと表示されているはずだ。

 ここで表示されたリストの中からadd:を選んでConnectボタンをクリックする。
同じように「ー」ボタンについてもAlbumControllerのremove:にConnectしよう。こうすることによって、ボタンが押された時にAlbumエンティティの新規追加と削除が行われる。

 最後は「+」ボタン、「ー」ボタンの状態変化の設定だ。例えば「ー」ボタンはAlbumリストで何かが選ばれていない状態では動作しないようにしなければならない。そのための設定を行う。インスペクタのBindingsでAvailabilityのenabledを設定する。「+」ボタンはBind to:でAlbumContollerを選び、Controller Key:にcanAddを選ぶ。Module Key Path:には何も選択しない。これで、エンティティを追加できる時だけ「+」ボタンが有効になる。「ー」ボタンも同じようにController Key:にcanRemoveを選ぼう。

 これで一通り設定は終わった。Interface BuliderのFileメニューからSaveを選んで、今までの設定をファイルに保存しておこう。

 じゃあ、プログラムを動かしてみようか。そう、もう最初に目標にしていたプログラムは出来てしまったのだ。Xcodeに戻って、プロジェクトウィンドウのビルドして実行ボタンをクリックすると、プログラムが作成されたあと、自動的に実行が始まる。(もし、エラーになるようだったら、どこかの設定が間違っていると思うので、最初に戻って間違いがないか順番に調べてみて欲しい)
 「+」ボタンでアルバムが追加されるし、タイトルやアーティストを入力したりもできる。ファイルに保存することも出来るのだ。

インデックス作成ツール/ユーザーインターフェース(その2)

 では、Interface Builderを使ってこの画面を作っていこう。


 画面の左側ではアルバムを表示して(1)、新しいアルバムの追加(2)や削除(3)を行うことにする。
 (1)のアルバムの表示にはNSTableViewという部品を使用する。パレットウィンドウの上のパネルからCocoa Data Viewというのを選んで、そのなかのNSTableViewをドラッグして、レイアウトウィンドウに持っていく。

 レイアウトウィンドウにTableViewを置いたら、サイズを適当に調整する。さらにインスペクタウィンドウを使って、テーブルのカラム数や、スクロールなどの設定を行う。インスペクタウィンドウは「Tools」メニューの「Show Inspector」を選ぶと表示される。これは、インタフェース作成の作業では一番良く使うウィンドウになる。インスペクタウィンドウで設定できることは非常にたくさんあるのだが、目に見える部分の細かい設定は”Attributes"で行う。

 まず、TableViewをダブルクリックしてテーブル全体の設定を行う。とりあえず、ここではタイトルだけを表示することにして、カラム数は1に、そしてスクロールバーは縦のみにしている。さらにカラムのタイトルをTitleにするため、カラムの設定を行う。カラムの設定をするには、ダブルクリックされた状態から編集したいカラムのタイトル行をクリックする。これでカラムごとの設定が変更できるようになる。とりあえずカラム幅を調整し、タイトル行を「Title」に変更しておく。

(2)と(3)はNSButtonという部品を使う。パレットウィンドウからNSButtonを選んでNSTableViewと同じようにレイアウトウィンドウにドラッグ&ドロップする。NSButtonを配置したらインスペクタウィンドウで形やボタンに描かれる文字などを設定する。追加ボタンには「+」、削除ボタンには「ー」の文字を表示するようにした。

 画面右側は、左側で選んだアルバムの属性を編集する画面だ。(4)(5)(7)はNSTextFieldを使う。今までと同様、パレットからレイアウトにドラッグ&ドロップする。

(7)は長文を書く場所なので、インスペクタを使って、テキストが折り返し表示されるように設定しておく。

(6)は日付を入力する欄なので、部品はNSDatePickerを使う。例によってパレットからドラッグ&ドロップしたら。インスペクタを使って日付だけを入力/表示するように設定しておく。

 ”Title" "Artist"などの文字は入力できないようにしてあるNSTextFieldである。これらもパレットからドラッグ&ドロップして適当にレイアウトウィンドウに配置する。ダブルクリックするとテキストが編集できるので、適当に修正しよう。

 これで一通りの画面レイアウトは終わりだ。次回はいよいとCocoa Bindingを使って、今作った画面とCore Dataのエンティティを繋いでみる。

インデックス作成ツール/ユーザーインターフェース(その1)

 さて、本来ならばここでBlogのデータを読んでくるところを作っていくべきなのだろうが、実はその部分の作りはなかなか難しいところなのだ。そこで、ちょっと寄り道。手動でアルバムの情報を入力するところを作ってしまおう。やっぱりなんか動くものが出来ないと寂しいし(笑)
 入力画面を作る時に、Cocoa Bindingという仕組みを使う。Cocoa Bindingというのは、Pantherから使えるようになったもので、極めて簡単に言ってしまうと、面倒なコードを書かなくてもプログラムが作れるような仕組みだ。とはいっても、ちゃんと動くようにするにはいろいろと考えないとならないことも多かった。それがTigerになってからはCore Dataと組み合わせることで、ぐんと使いやすくなっているように思う。それがどんなもので、どういう仕組みになっているかについては、実例を使って説明した方がわかりやすいだろう。
 ということで、これからしばらくは、Core DataとCocoa Bindingを使って実際にデータを入力する画面を作る方法について書いていこう。

 ユーザーインターフェースを作るには、まずプロジェクトの中からMyDocument nibというファイルを選んでダブルクリックする。するとInterface Builderというアプリケーションが起動して画面やメニューを編集できるようになる。Interface Builderの画面の簡単な説明はsite-aroさんのCocoaハヤッパリにある”はじめてのCocoaアプリ”を読んでもらうと分かると思う。
 最初はデザインウィンドウの真ん中にある”Your document contents here"というテキストを取りのぞくことから始めよう。
 そうしたら、パレットウィンドウからパーツを選んで画面を作っていく。とりあえず、最初はアルバムを追加してその属性を編集する画面を作ることにする。最終的にはこんな画面にする予定だ。

インデックス作成ツール/データモデリング(その4)

 では、エンティティとエンティティの間の関係を設定しよう。まずはAlbumとSongListとの間に関係を設定する。

 Albumエンティティを選択した後、プロパティの追加ボタンをクリックして、「関係を追加」を選ぶ。これで、リストにnewRelationshipという名前で新しい関係が作られる。

 例によって左上の画面で関係の詳細を決めていく。名前、オプション、一時については属性の時と同じだ。SongListに対する関係なので、名前はsongListとしておく。ディスティネーションには関係付けるエンティティを指定する。当然SongListエンティティを選ぶ。
 「逆」は今は選べない状態のはずだ。ここはAlbumからSongListに向かう関係のみが設定されていて、SongListの方からはAlbumに対する関係は設定されていない状態ということだ。これは相手側(この場合はSongListエンティティ)の方に関係を追加すると、選べるようになる。
 「対多関係」にチェックを入れると、エンティティ一つに対して関係する相手が多数あるということになる。一つのアルバムには普通は何曲も入っているものだから、ここはチェックを入れよう。
 「ルールを削除」は英語版での表示はDelete Ruleで「削除のルール」と訳すべきところだ。(しかしひどい訳だな(^^;)エンティティを削除するときにこれに関係しているエンティティとの関係をどうするかを指定するところだ。ここの選択肢、アクションなし(No Action)、無効にする(Nullify)、重ねて表示(Cascade)、拒否(Deny)もなにがなんだか分からない訳なので、ここは英文に当たった方が良い。
 簡単に説明すると以下のような設定らしい。
 No Actionはその名の通り、削除されても何もしない。
 Nullifyはこのエンティティが削除されたら、相手のエンティティ側の関係プロパティを空にする。ただし、相手のエンティティ自体はそのまま残す。たとえば、アルバムの収録曲を削除するケースを考えてみよう。この場合、SongListエンティティが削除されるのだが、このときにAlbumエンティティは削除されたSongListとの関係を切る。が、Albumエンティティ自体は無くならないで残っている。このようなときにはNullifyを選択する。
 Cascadeはこのエンティティが削除されたら、関係している相手のエンティティも一緒に削除する。さっきとは逆にAlbumエンティティが削除された場合を考えてみよう。このときには収録されている曲はすべて削除されるので、このAlbumエンティティと関係しているSongListはエンティティごと削除される。このような場合はCascadeを選択する。ちなみにcascadeの辞書的な意味は、順送りに伝える、順々に並べるといったものだ。(もともとは階段状に連続する滝といった意味からこうなっているらしい。)
 最後のDenyだが、これは関係しているエンティティがまだ存在している時には、削除自体出来ないようにする設定だ。アルバムと収録曲の例で、アルバムを削除したら収録曲が勝手に消えてしまうことがないようにしたい場合、Denyを指定するといい。

 というわけで、この場合の関係は、CascadeかDenyが適切ということになる。ここはCascade(重ねて表示)を選んでおこう。

 さて、同じようにSongListにも関係を追加しよう。SongListにはAlbumとSongへの関係を追加する。Albumエンティティの時と同様にプロパティ画面で関係を追加して、左上の画面で編集する。Albumエンティティへの関係はalbumという名前に、Songエンティティへの関係はsongという名前にする。

 albumのディスティネーションにAlbumを指定すると、今度は「逆」の選択肢にsongListが現れるので、これを選択する。これは先にAlbumエンティティに追加してあったsongListプロパティ(関係)のことだ。SongListの方で「逆」の設定をしておくと、自動的にAlbumエンティティのsongListプロパティの方にも「逆」設定が追加される。ディスティネーションで選ぶのはエンティティだったが、「逆」で選べるのはプロパティであることに注意しよう。

 この手順を繰り返して、エンティティ間の関係を設定していく。今回の設定はここにまとめてある。

 すべての設定が終わると、下の画面にはこのような図が出来ているはずだ。以前にここで書いた下の図と比べてみて欲しい。ここまでで、このプログラムで扱うデータの設計が終わったことになる。この作業はデータモデリングと呼ばれる。

インデックス作成ツール/データモデリング(その3)

 では、エンティティにプロパティを追加していこう。まずは、Albumエンティティのプロパティを追加する。エンティティリストから「Album」を選んでおいてから、真ん中のプロパティ画面の「+」ボタンをクリックする。エンティティの時は、クリックするとすぐにエンティティが追加されたが、プロパティの場合は種類を選ぶリストが表示される。

 実はプロパティには種類がある。属性(attribute=意味はそのまんま属性)、関係(relation=これもそのまま関係という意味)、受信済みプロパティ(fetched properties、fecthは取ってくるという意味。しかし、この日本語訳はなんとかならんのか)の 三つだ。
 属性というのは、そのエンティティの中に持っているデータのことだ。アルバムだったら「タイトル」とか「リリース日」にあたる。
 関係というのは、他のエンティティとの関係になる。以前に書いたデータの図で
データのまとまりの間に線を引いていたが、この線の部分に当たるものだ。
 受信済みプロパティとは、条件を付けて、その条件に合うエンティティとの関係ということらしい。私もまだあんまりピンときてない。今回はまだ使わないので、とりあえず忘れておこう(^^;

 というわけで、まずは属性から追加してく。「+」ボタンをクリックした後、表示されたリストから「属性を追加」を選ぶ。すると、プロパティリストに「newAttribute」という名前で新しい属性が表示される。右上の編集画面でこの属性の内容を決めていこう。

 最初は、名前、オプション、一時、タイプ、の四つの項目が編集できる。名前はもちろん属性の名前。属性の名前には、先頭の文字は英小文字でないといけないという規則がある。オプションは、ここにチェックを入れておくと、この属性は値が無くてもいい、という意味になる。一時は、チェックを入れておくとファイルに保存する時にこの属性が保存されない。タイプは属性の種類である。
 
 タイプを指定すると、その下に、属性値として持てる値の条件と、最初にエンティティが作られた時にデフォルトで設定される値を指定する画面が表示される。この部分はタイプの種類によって変わってくるため、最初は表示されていなかったのだ。

 図は文字列の場合だ。文字列の場合、ここでは、長さの最小と最大、入力できる文字列の形式(正規表現の欄)を条件として指定できる。
 アルバムタイトルを格納する属性の場合、名前を「title」とし、オプションと一時のチェックは両方とも外しておく。タイプは文字列を選ぶ。
 条件としては、最小長に1を入れて、あとは空白にしておく。デフォルト値は「Title」にしておこう。

 同じようにしてAlbumや他のエンティティの属性を追加していく。どんな属性を追加したかは、こちらの表を見て欲しい。

 次は、関係を追加する。が、それはまた別の記事で。

インデックス作成ツール/データモデリング(その2)


 これが編集用の画面。大きく上下二つに分かれていて、さらに上の部分は三つに分かれている。

 まず、左上はエンティティの追加や削除を行うところ。Core Dataでは、「アルバム」や「曲」のようなデータのまとまりのことを、エンティティ(Entity=実存といった意味)と呼んでいる。この画面の左下にある「+」「ー」のボタンで追加と削除が出来るようになっている。追加したエンティティはここにリストで表示される。

 次に上段中央の部分、ここは、プロパティの追加や削除を行う部分である。プロパティ(property=特質、特性とかいった意味)というのは、エンティティの中に含まれている情報そのもの、例えば「アルバム」エンティティだったら、「タイトル」だとか「アーティスト」だとかだ。ここも「+」「ー」で追加・削除が出来る。追加したプロパティがリスト表示されるのも同じだ。

 右上は左や中央で選んだエンティティやプロパティの編集画面だ。リストからエンティティやプロパティを選ぶと、その詳細を編集できる。詳しいことはプロパティを編集する時に説明することにしよう。

 下段には編集したデータの内容がこんな風に図で表示される。

 ではまず、エンティティとして「Album」「Song」「SongList」を作ろう。エンティティ追加の「+」ボタンをクリックすると、新しいエンティティが「Entity」という名前で追加される。追加されたエンティティをクリックすると、名前を変更できるようになるので、名前を「Album」に変更する。同じように「Song」「SongList」を作る。

 エンティティが出来たら、それぞれのエンティティのプロパティを作っていくのだが、長くなるので、例によって続きは後日。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。