Hatena::ブログ(Diary)

Watsonのメモ RSSフィード

2011-10-02

MacRuby でサービスメニューに対応したアプリを作る

お久しぶりです。今日は朝からサービスメニューと格闘しておりました。みなさんはサービスを使っていますか?メニューをたどるとありますよね。

f:id:Watson:20111002122418p:image

さっそく作って行きましょう。

info.plistを編集

プロジェクトを作成したら、"プロジェクト名-info.plist" を開いて以下のように「Services」の内容を追加します。

f:id:Watson:20111002123030p:image

"info.plist"をエディタで直接編集する場合には、以下の記述を追加します。

	<key>NSMainNibFile</key>
	<string>MainMenu</string>
	<key>NSPrincipalClass</key>
	<string>NSApplication</string>
---- 次の行から
	<key>NSServices</key>
	<array>
		<dict>
			<key>NSMessage</key>
			<string>doService</string>
			<key>NSPortName</key>
			<string>Service</string>
			<key>NSSendTypes</key>
			<array>
				<string>NSStringPboardType</string>
			</array>
			<key>NSMenuItem</key>
			<dict>
				<key>default</key>
				<string>MacRuby Service Test</string>
			</dict>
		</dict>
	</array>
---- 上の行までを追加する
</dict>
</plist>

今回追加したのは、以下の4つの情報。

  • NSMessage (Instance method name)

サービスが実行されると、呼び出されるメソッド名を記述

  • NSPortName (Incoming service port name)

サービスを処理するアプリケーション名

  • NSSendTypes (Send Types)

サービスに対応するデータの種類

  • NSMenuItem (Menu)

サービスメニューに表示するメニュー名

サービスの処理を行ったあとで、サービスを呼び出したアプリケーションにデータを返したりする場合にはもう少し記述を追加する必要があるみたいです。

サービスを処理するメソッドを実装

info.plist の NSMessage で追加したメソッドを実装します。メソッドは以下の形式で定義します。

def doService(pboard, userData:userData, error:error)

定義したメソッドで、サービスの処理内容を実装します。

サービスにアプリケーションを登録

アプリケーション起動時にサービスへ登録しないといけないようなので、NSApp.setServicesProvider(self) というコードを applicationDidFinishLaunching に追加します。

def applicationDidFinishLaunching(a_notification)
  NSApp.setServicesProvider(self)
end

実行

実装が完了したら、ビルドしたアプリをアプリケーションフォルダか ~/Library/Services にコピーします。サービスメニューを更新するために再ログインします。

次にシステム環境設定でサービスを有効にします。

f:id:Watson:20111002130301p:image

今回のアプリケーションでは NSStringPboardType に対応しているので、他のアプリケーションで文字列を選択した状態でサービスを呼び出すと、選択範囲の文字列が渡されます。

最終的に実装したものは以下のようになりました。サービスで渡された文字列を Google Translate API で英語から日本語に翻訳して表示します。

# Google Translate API key
API_KEY = 'AIzaSyDNLefOLDCAlDm5niZP_2LX7RIEdmnPwbM'

require 'json'
require 'uri'
require 'open-uri'

class AppDelegate
  attr_accessor :window
  attr_accessor :text # Text View Outlet

  def applicationDidFinishLaunching(a_notification)
    NSApp.setServicesProvider(self)
  end

  def doService(pboard, userData:userData, error:error)
    window.makeKeyAndOrderFront(nil)
    string = pboard.stringForType(NSStringPboardType)

    translate(string)
  end

  def translate(string)
    source = 'en'
    target = 'ja'
    
    if string.length > 0
      open(URI.escape("https://www.googleapis.com/language/translate/v2?key=#{API_KEY}&source=#{source}&target=#{target}&q=#{string}")) {|f|
        str = f.read
        js = JSON.parse(str)
        text.setString(js['data']['translations'][0]['translatedText'])
      }
    end
  end
end

f:id:Watson:20111002130826p:image

ソースコード

から取得できます。

参考にしたサイトは、

です。

それでは、みなさんおもしろいサービスを作ってみてください!(^o^)/

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/Watson/20111002/1317529322