Core DataアプリでNSPredicate

Mac用のTwitterクライアントアプリを作っているけれども、興味本位というか趣味の問題でCore Dataを利用している。データストアはSQLiteだ。XMLよりはよさそう。

で、今回のバージョンアップで、タイムラインを2種類表示できるようにした。

標準のWebページで言うと、フォロワーも含めた「ホーム」で見れるタイムラインと、自分のだけが見れる「プロフィール」でのタイムライン。

それをアプリでは「HOME」と「My」というタブの名前で表現して実装した。

データとしては、「My」は「HOME」の部分集合になるはずなので、「My」タブ用に新しくデータを取得する必要はないであろうことはすぐに思いついた。

Core Dataアプリケーション(今回はCollectionViewを使っている)ではInterface Builder上で見ると、ArrayController→CollectionViewItem→CollectionViewItemViewというつながりになっていて、ArrayControllerが実際のデータストアのエンティティを参照することになっている。

今回は、これをまず、二組用意し(コピーでOK)、名称を変更して、コピーで作成した新しいViewItem, ViewのそれぞれのItemが新しいArrayControllerの項目を参照するように設定した。

ここまでの設定で、「HOME」タブと「My」タブは同じ情報が表示されることになる。

で、「My」タブの方のArrayControllerにだけfilter predicateを設定する。調べたところ、これはSQLのWHERE句のようにデータ取得の時にフィルタリングするのではなく、データを全件取得してからビューに渡すときに絞り込むためのものだという。効率をコンパイラが最適化してくれるかは心配だが、メモリ的には「HOME」タブ用に全件取得「してしまっている」のでビューのために絞り込む方式で問題はないだろうと、こちらを選択した。fetchRequestオブジェクトを利用するより簡単にできた。条件には、OAUTH認証に成功したときに戻り値として返ってくるTwitterアカウント(属性名screen_name)を利用している。

条件式が固定ではない(認証したアカウントが条件式になるため、コンパイル時には条件式が決まらない)ので、Interface Builderでは設定できないので、Xcodeで自動生成されたAppDelegateクラスのawakeFromNib関数で設定している。ここならばInterface Builderで構築したWindowなどのコントロール類すべての初期化(実体化・メモリへのロード)が終わっているから操作がすべてできる。

手探りなので、最適解がわからない状態で作っている。どこかのタイミングでソースをブラッシュアップしなければならない気はしているけれども、自分が使っていて困らないとつくらないので作業が進まない。ユーザゼロでは。

一応ここから。
KIMWitter 最新バージョンはVersion 0.2

コメント