サービス機能のサポート

Cocoaに関するヌマタメモ
2008年11月29日 22:49

※ あまり自信がない。

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 で保存しなければ正常に反映されないことに注意。

コメントを書く


トラックバックはありません。

トラックバックURL: http://numata.designed.jp/mt-tb.cgi/55