※ あまり自信がない。
1. サービスを処理するオブジェクトの用意
サービスを処理するためのオブジェクトを用意する。インスタンスさえ存在するのであれば、どのようなオブジェクトでも構わない。その中で、以下のように処理メソッドを定義する。メソッド名だけは自由だが、その後のオプションは変更してはいけない。
- (void)myServiceMethod:(NSPasteboard *)pboard
userData:(NSString *)userData
error:(NSString **)error;
このように、サービスで受け渡されるデータはペーストボードを介してやってくる。実装部分では、まず、この処理メソッドが対応している形式のデータを持っていることを確認しなければならない。エラー処理は、このように *error にエラー文字列を指定してリターンすることで行う。
NSArray *types = pboard types;
if (!types containsObject:NSStringPboardType) {
*error = @"Error: couldn't get text.";
return;
}
次に、このペーストボードからデータを取得する。ここでも一応エラー処理は忘れずやっておく。
NSString *pboardString = [pboard stringForType:NSStringPboardType];
if (!pboardString) {
*error = @"Error: couldn't get text.";
return;
}
最後に、取得した文字列を利用して何らかの処理を行う。このアプリケーションをアクティブにする場合には、
[NSApp activateIgnoringOtherApps:YES];
と書いておく。
呼び出し元のデータを上書きするには、
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[pboard setString:@"apple orange" forType:NSStringPboardType];
のようにして新しいデータをペーストボードにセットする。
2. サービスの登録
NSApplication の delegate で、applicationDidFinishLaunching: を実装し、その中で以下のようにして手順1で用意したサービスを処理するオブジェクトを登録する。もちろん self でも良い。
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[NSApp setServicesProvider:anObj];
}
サービスの処理メソッドは、この setServicesProvider: メソッドが終了した時点から呼び出されるようになる。applicationDidFinishLaunching: が終了したあとではないので注意する。applicationDidFinishLaunching: ではウィンドウの表示などの処理も行うことが多いため、いちばん最後にこれを書いてやる方が良い。
3. サービスの告知
OS は、/Applications か ~/Applications に置いてあるアプリケーションの Info.plist から、サービスに関する記述を読み取ってこれをサービスメニューに追加する。
Project Builder の「ターゲット」タブから 「Info.plist のエントリ」の詳細設定ビューを開き、「同位置に新規作成」を押して、以下のような構造でサービス告知のためのエントリを追加する。
NSServices(配列) 0(辞書) NSPortName(文字列) アプリケーション名 NSMessage(文字列) メソッド名 NSSendTypes(配列) 0(文字列) NSStringPboardTypeなど NSReturnTypes(配列) 0(文字列) NSStringPboardTypeなど NSMenuItem(辞書) default(文字列) メニュー項目の名前 NSKeyEquivalent(辞書) default(文字列) ショートカットキーを1文字で 1 ...
ここで、アプリケーション名は、そのままアプリケーションの名前である(つまり通常はアルファベットで半角スペースを含まない文字列)。
メソッド名は、手順1で定義したメソッドの名前である。上の例では、「myServiceMethod」。
NSSendTypes と NSReturnTypes はサービスで対応するデータの種類である。サービスの処理メソッドが対応するのであれば、複数個あっても良い。また、NSReturnTypes の定義はオプションであり、呼び出し元のデータを上書きするのでなければ指定しない。
メニュー項目の名前は、階層構造のメニューにする場合には、「EIJIRO Viewer/Search Selection」のように『/』で区切る。
ショートカットキーの定義もオプションである。他のアプリケーションとかち合った場合には名前が若い方が勝つので注意する(それってどうよ)。
4. OSにサービスを提供しているアプリケーションがあることを知らせる
/Applications か ~/Applications にアプリケーション本体をコピーして、ログインしなおすか再起動するか以下の関数を呼び出す。なお、ゴミ箱の中に同じアプリケーションのコピーがあるとそちらが呼び出される場合があるので注意する。
void NSUpdateDynamicServices(void)
5. ローカライズ
ServicesMenu.strings というファイルを作って、NSMenuItem で指定した名前をキーにしてローカライズ文字列を指定し、English や Japanese のローカライズを行う。このファイルは UTF-16 で保存しなければ正常に反映されないことに注意。
コメントを書く