SIMBL で Cocoa アプリケーションにコードをつぎたす
Cocoa アプリケーションは Input Manager という仕組みを使って拡張できて GreaseKit でもこれを使っている。Input Manager は Leopard からホームディレクトリにいれられなくなったり、パーミッションをいじらなきゃいけなかったり、素で使うのが面倒になってしまったので SIMBL 経由で使うのが楽だと思う。
というわけで、SIMBL に読み込ませるバンドルの作り方をさわりだけ説明します。
まず Xcode で新しいプロジェクトを作る。左側で Mac OS X の Bundle を、右で Cocoa Bundle をえらぶ。
プロジェクトが出来たらクラスをひとつ定義しておく。.m ファイルと .h ファイルを新規に作る。
名前はとりあえず MainController にした。
ここで定義したクラス名は元アプリケーションとかぶれないので注意が必要だ。MainController はありがちすぎるので、プリプロセッサでドメインを逆さまにしたものをつけて逃げてみた。
#import <Cocoa/Cocoa.h> #define MainController ComExampleMainController @interface MainController : NSObject { } @end
次に、MainController に load メソッドを追加する。 load は NSObject のクラスメソッドで、クラスの読み込み後に呼ばれる。
Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.
load メソッドを追加した MainController.m はこんな感じになる。
#import "MainController.h" @implementation MainController + (void) load { NSLog(@"hello"); } @end
最後に SIMBL 用の項目を Info.plist に足しておく。アプリケーション起動時に SIMBL が読まれると、SIMBL は個々のバンドルの Info.plist を読んで、いま起動したアプリケーションに一致するものだけを読み込む。
今回はあらゆるバージョンの Safari を指定するべく、以下の項目を Info.plist に追記する。
<key>SIMBLTargetApplications</key> <array> <dict> <key>BundleIdentifier</key> <string>com.apple.Safari</string> </dict> </array>
Info.plist はプロパティリスト用のちゃんとした編集画面があるけど、慣れない人はオフにしちゃってもいいと思う。
Xcode の作業はここまで。バンドルをビルドして、特定の場所にコピーする。
% cd ~/Library/Application\ Support/SIMBL/Plugins/ % ln -s ~/Desktop/Hello/build/Debug/Hello.bundle % ls Hello.bundle@ % /Applications/Safari.app/Contents/MacOS/Safari 2009-02-01 23:05:48.080 Safari[30368:10b] hello %
地味だけどちゃんとコードが実行されて hello とでている。あとは [NSApplication sharedApplicaton] とか [NSNotificationCenter defaultCenter] とかクラスメソッドがいくつかあるので、そこからオブジェクトをたぐりよせて、えーと、いろいろできます。