LoginSignup
15
19

More than 5 years have passed since last update.

Macでオリジナルプロトコルを実装してみた

Last updated at Posted at 2014-04-12

Macでオリジナルプロトコルを実装してみた

2014/04/13 にシェルコマンドで空白を用いたい場合の処理を追記しました

私は、普段からコマンドラインランチャーとして、 Alfred というアプリケーションを使用しています。

Alfredでは、URLとコマンドキーワードを設定すれば、そのキーワードでURLを開く(たとえば、キーワード「google」でGoogle検索のURLを開く)ことができます。
私は、常々このAlfredでシェルコマンドを起動させることはできないかなーと考えていました。
(注:実はシェルコマンドの起動はAlfred ProもしくはAlfred 2を買えばビルトインで実装されていますが、私はお金払いたくないので実装しました)

そして、Macのアプリケーションには、iTunesの「 itunes: 」のような オリジナルプロトコル が実装されているものがあります。
なので「 shell: 」というオリジナルプロトコルが実装されている AlfredShellRunner というアプリケーションを作って、
Alfredでシェルコマンドを起動できるようにしてやろう、と考えました。

( 要訳: Alfredというアプリでシェルコマンドを起動させたいからオリジナルプロトコルがついてるアプリケーションをつくるよ)

参考:
OSXでオレオレ・プロトコルのヘルパアプリケーションを作成する - http://blog.katsuma.tv/2007/12/osx_protocol_helper.html

アプリケーションの構成

Macでのアプリケーションは、 .app という拡張子がついたディレクトリによって表しています。

AlfredShellRunner.app
    - Contents/
        - Info.plist
        - MacOS/
        - Resources/

オリジナルプロトコルを実装するには、 Info.plist を使用します。

Info.plist

Info.plistは、アプリケーションの設定情報(アプリケーション名やアイコンファイルパス等)を XML にしたものです。
オリジナルプロトコルの情報は、このInfo.plistに記載します。
その歳、「 CFBundleURLTypes 」というKEYタグを使います。

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>Alfred Shell Runner URL</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>shell</string>
        </array>
    </dict>
</array>

こんなかんじ。

CFBundleURLTypes には、これらのキー情報を設定出来ます。

  • CFBundleTypeRole (必須) - string
  • CFBundleURLIconFile - string
  • CFBundleURLName - string
  • CFBundleURLSchemes - array

CFBundleTypeRole

このキーは、URL タイプを尊重した、アプリケーションの役割を指定します。値は Editor、Shell、None のいずれかとすることができます。
(引用元: http://potting.syuriken.jp/potting_conv/BPRuntimeConfig_J/chapter3.html)

CFBundleURLIconFile

このキーは、この URL タイプに対して用いるための、アイコン画像ファイルの(拡張子を除く)名前を格納します。
(引用元: http://potting.syuriken.jp/potting_conv/BPRuntimeConfig_J/chapter3.html)

CFBundleURLName

このキーは、この URL タイプのための抽象化された名前を格納します。このキーは特定のタイプを参照するための主な手段となります。
また、この名前はタイプ名の「人が読める版」を提供するために、InfoPlist.strings ファイル内のキーとしても使用されます。
(引用元: http://potting.syuriken.jp/potting_conv/BPRuntimeConfig_J/chapter3.html)

CFBundleURLSchemes

このキーは文字列の配列を格納しており、そのそれぞれは、このタイプによって取り扱われる URL スキームを識別します。
(引用元: http://potting.syuriken.jp/potting_conv/BPRuntimeConfig_J/chapter3.html)

アップルスクリプトを書く

AppleScriptエディタを開いて、以下の内容を入力。

on open location shellURL
    if shellURL starts with "shell://" then
    -- "shell"プロトコルを開いた場合
        activate
        set len to the length of shellURL
        set shelltext to text from character 9 to character len of shellURL
        -- "shell://" 以降の文字列を取得

        tell application "Applications/Utilities/Terminal.app"
        -- Terminal.app を起動
            activate
            do script with command shelltext
            -- シェルスクリプトを実行
        end tell

    end if
    quit
end open location

(追記2014/04/13) シェルコマンドに空白を用いたい場合

上記のapple scriptだと、 shell://python -c 'print "hello"' のようなシェルコマンドを使うことはできません。なぜなら、URLスキームでは空白が %20 という文字に置換されるからです。

しかし、AppleScriptには文字列置換はできません。なので delimitors という機構を使います

on replace(src, tg, rp)

    set oldDel to AppleScript's text item delimiters
    set AppleScript's text item delimiters to tg
    set myList to text items of src
    set AppleScript's text item delimiters to rp
    set myText to myList as string
    set AppleScript's text item delimiters to oldDel
    return myText

end replace

これで文字列を置換する関数が設定できました。
あとは、AppleScriptに文字列を置換する一行を書けば良いだけです。


on replace(src, tg, rp)

    set oldDel to AppleScript's text item delimiters
    set AppleScript's text item delimiters to tg
    set myList to text items of src
    set AppleScript's text item delimiters to rp
    set myText to myList as string
    set AppleScript's text item delimiters to oldDel
    return myText

end replace

on open location shellURL
    if shellURL starts with "shell://" then
    -- "shell"プロトコルを開いた場合
        activate
        set len to the length of shellURL
        set shelltext to text from character 9 to character len of shellURL
        set shelltext to replace(body, "%20", " ")
        -- "shell://" 以降の文字列を取得して%20を置換

        tell application "Applications/Utilities/Terminal.app"
        -- Terminal.app を起動
            activate
            do script with command shelltext
            -- シェルスクリプトを実行
        end tell

    end if
    quit
end open location

入力したら、ファイル->保存で「 ファイルフォーマット 」を「 アプリケーション 」にして保存。

Info.plistにプロトコル情報を追記

これでアプリケーションは完成したが、この状態では まだオリジナルプロトコルの内容がInfo.plistに書かれていない状態 です。
なので、上記のオリジナルプロトコルの記述を、 保存したアプリケーション/Contents/Info.plist に追記してください。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleAllowMixedLocalizations</key>
    <true/>
    <key>CFBundleURLTypes</key>
    (省略)
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLName</key>
            <string>Alfred Shell Runner URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>shell</string>
            </array>
        </dict>
    </array>

</dict>
</plist>

追記すると上記のようになります。

保存したアプリケーションをdmgにする

しかし、追記しただけではまだダメです。この追記したInfo.plistを実行させるには、アプリケーションを一度 .dmg ファイルに圧縮して、インストールする必要があります。
DMGに圧縮する方法はこちらを参考にしてください。 -> http://memorva.jp/internet/mac/dmg_disk_image_file.php

アプリケーションをdmgにして、再度インストールして実行すると、もうオリジナルプロトコルが実装されています。
あとは、AlfredでカスタムURL検索で shell://{query} と入力すれば完了!!!

15
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
19