Core Data Document-based アプリケーションで File Wrapper を使う

Core Data アプリケーションと Document-based アプリケーションをあわせたものが Core Data Document-based アプリケーション。RubyCocoa にはテンプレートがあって、それを使うとあまり問題なくできるようなので、とりあえずメモはしない(試してないから)。

ただ、Document-based アプリケーションと違って、NSDocument のサブクラスを作るのではなく、NSPersistentDocument のサブクラスを作っている。これにはいろいろ問題があるらしく、RubyCocoa の問題ではなく Cocoa でも、Autosave ができなかったり、保存するファイルに File Wrapper が使えなかったりする。File Wrapper とは、ファイルのように見えるけど、実はフォルダで、そのフォルダに拡張子がついていて、利用するアプリケーションがインストールされていると Mac OS からはファイルに見えるもの。いわゆるパッケージになってるやつね。iMovie とか iPhoto とかのファイルがそうなってる。

さて、さすがにこんなのは自分で何ともできるわけはないので、いろいろと探したら、RubyCocoa でこれをできるようにしてくれた人がいた。

英語だけど、ここに詳しく乗っていて、コードをコピペすれば問題なく動くようになる。自分用のメモとしては、ちょっとした注意と、あと、これだけではちょっと問題があったところを強引に手を加えたものをここに書いておく。

まず、そのページでは、PersistentPackageDocument という NSPersistentDocument のサブクラスを作っている。RubyCocoa でこれをするときは、プロジェクトに NSObject のサブクラスのファイルを追加して、クラス名と継承するクラス名を書き換えたらいい。

そして、元からある MyDocument を NSPersistentDocument のサブクラスから PersistentPackageDocument のサブクラスに変える。これは、継承するクラス名を変えるだけでいい。

あと、もう一つファイルを追加して、PersistentPackageDocumentController という NSDocumentController のサブクラスを作って、そこでもいろいろしてる。まあ、全部コピペして、エラー処理を加えるだけで動く(エラー処理なくても動くけど)。

最後に、一番下に書いてあるんだけど、Xcode のプロジェクトファイルでターゲットのドキュメントタイプでパッケージのところにチェックを入れる。

さてさて、これだけで、Core Data Document-based アプリケーションで File Wrapper が使えるんだけど、使ってみて細かいことだけど気になることがあったので、手を加えてみた。

スクリプトで対処したのは、現在のディレクトリの情報。これは、自分の環境だけかもしれないけど、最初の書類では問題なくても2つ目の書類を新規ではなく開いたときなんかに、Open パネルに表示されるカレントディレクトリが開いている書類のパッケージの中になってしまった。というわけで、Open パネルが開くときに参照する現在のディレクトリを、NSDocumentController のcurrentDirectory をオーバーライドすることで対処する。もうちょっとスマートなやり方が見つかったらまた書き換える。

def currentDirectory

if super_currentDirectory.to_s.match(/(your extension)$/)

return super_currentDirectory.to_s.gsub(//[^/]+?.(your extension)$/,"")

else

return super_currentDirectory

end

end

これを、PersistentPackageDocumentController に加える。何をしてるかというと、currentDirectory で Open パネルが開く前にこのメソッドが呼ばれるので、super_currentDIrectory でその時点でのカレントディレクトリを得て、パッケージの拡張子で終わっていたら、そのままだとパッケージの中が表示されるので、パッケージファイル名をディレクトリから消して返す。そうでなければそのまま返す。

もう一つ、Save As... を使ったときもおかしいんだけど、どこで手を加えるのか探すのが面倒になったので、Save As... そのものを消してしまった。有効な対象法が見つかったらまたここに書き加える。とはいえ、次にこれを使うのがいつになるかわからないので、永遠にこないかも。