消えた NSMovieView

リモート AppleEvent の続きが気になるところですが(気にならない?)、ちょっと中断。

iTunes のポッドッキャスト。音声/映像の配信に興味があって試してみたりしています。ポッドキャストは、RSS なこともあって RSS 同様(わけの分からない説明です)ほっておくとどんどん記事(音声)が溜まっていきます。

テキスト情報ならまとめて読むことも可能ですが...音声をまとめて聞くのは少し気合いを入れないと消化できません。iTunes は、管理するのには最適なんですが。

どうにかならないものか...と思案して、AppleScript Studio でポッドキャストの再生、通知アプリケーションを作ろうと思い立ちました。

現在、こんな画面になっています。プログラム的になんら難しいことをしていないのに、ここまでくるのに 3 日間かかっています。問題は、NSMovieView。これ、Interface Builder からなくなっていませんか?探したが見当たらず。仕方がないので Developer Tools 付属のサンプル Talking Head の NSMovieView をコピーしていました。しかし、低機能すぎます。

もしかして、QTMovieView を使えってことなのでしょうか?といっても、AppleScript Studio には QTMovieView を使うための Class は用意されていません。QTMovieView に tell movie view 〜 としてもエラーになるばかり。

最終的に NSMovieView はあきらめて、おとなしく QTMovieView を使うことに決定。もちろん、call method で操作します。って、なんで音声や映像を再生するだけのために call method を使わにゃならんねん。

リモート AppleEvent (3)

有線 LAN で接続した Mac を遠隔操作。一回目は、前準備。二回目は、スクリプトを書いて Mac を動かしました。今回は、前回提起された問題。認証ダイアログの抑制について。

そもそも、パスワードやユーザ名などは、Mac の場合「キーチェーンアクセス」というアプリケーションが一括管理してくれます。もちろん、リモート AppleEvent でのホスト側のこういった情報も管理してくれています。

キーチェーンアクセスは、/Application/Utilities/ にあります。起動します。デフォルトの設定を変えていないなら、ログインというキーチェーンがあると思います。前回のスクリプトを実際に試してみたなら、ホスト側の名前がついたインターネットパスワードという種類のキーがあると思います(この場合、iBook800.local)。ない場合は、作成してください(作成方法は割愛)。

これを選択するとキーチェーンアクセスのウィンドウ上部に情報が表示されると思います。アカウント(ユーザー名)と場所(eppc://iBook800.local:3031)が書かれています。前回、ホストを指定するのに eppc://iBook800.local しか指定していませんでした。最後のコロン以下の 3031 は、リモート AppleEvent が利用するポート番号です。

キーチェーンアクセスにこうやって保存されているなら、AppleScript では「Keychain Scripting」というバックグラウンドアプリケーションを使ってキーチェーンや登録されているキーの情報を取得することができます。

ここで問題が出てきます。Mac OS X 10.3 と 10.4 の Keychain Scripting は、バグがあってそのままではすんなりと利用できません。10.4.2 のアップデータでなおったとありますが、本当はなおっていません。この問題を回避するためにアップルは情報を公開しています。しかし、ここで紹介されているスクリプトを試してもエラーになります。というのも、このスクリプト自体が間違っているから。

Keychain Scripting は、パスワードを要求されると「Keychain Scripting でエラーが起きました:アプリケーションは実行されていません。」とエラーが表示されます。これが、Keychain Scripting のバグです。

tell application "Keychain Scripting"
    password of key 1 of keychain 1
end tell

-- Keychain Scripting でエラーが起きました:アプリケーションは実行されていません。

なぜ、こんなエラーが起きるかの原因は分からないですが、次のような手順で回避できます。(1) Keychain Scripting が起動しているなら、一度終了させる。(2) Finder で開く。アップルも同じような解決方法を掲載しているわけですが、(1) の部分に問題がありそのままでは利用できないものになっています。

掲載されているものでは System Events で Keychain Scripting のプロセスを調べて System Events の中で Keychain Scripting を終了させています。

tell application "System Events"
    quit targetApp
end tell

これが間違い。System Events ではアプリケーションを指定して終了させることはできません。結果、プロセスはそのまま残るので再度エラーになります。まずは、このバグを回避するために次のようなスクリプトを作成します。

on run
    startKeychainScripting()

    tell application "Keychain Scripting"
        password of key 1 of keychain 1
    end tell
end run

on startKeychainScripting()
    -- Keychain Scripting の起動確認
    tell application "System Events" to set bool to exists process "Keychain Scripting"

    -- 起動しているなら終了
    if bool then
        keychainScriptingKiller()
        -- System Events からプロセスが見えなくなるまで
        --これがないと Finder でエラーが発生する
        repeat
            tell application "System Events" to set bool to exists process "Keychain Scripting"
            if not bool then exit repeat
        end repeat
    end if

    -- Keychain Scripting の再起動
    restartKeychainScripting()
end startKeychainScripting

on restartKeychainScripting()
    -- kscr は、Keychain Scripting のクリエータータイプ
    -- com.apple.KeychainScripting でも可
    -- Finder で Keychain Scripting を起動
    tell application "Finder" to open application file id "kscr"

    -- System Events からプロセスが見えるようになるまで
    --これがないと次の処理でエラーになる
    repeat
        tell application "System Events" to set bool to exists process "Keychain Scripting"
        if bool then exit repeat
    end repeat
end restartKeychainScripting

on keychainScriptingKiller()
    tell application "Keychain Scripting" to quit
end keychainScriptingKiller

いつもよりコメントを多めにしています。安全のために Keychain Scripting を利用する度に「終了/Finder で開く」の処理を行っておきます。

これが他の環境でも動くかどうか分からないですが。シェルを使っての起動、終了でもいいと思います。もし、動かない場合はシェルでやってみるといいかもしれません。

しかし、キーチェーンを利用するまでに時間がかかりますね...。

リモート AppleEvent (2)

さて、前回の準備はできたでしょうか? Ethernet で接続した iBook と iMac。iMac の方から iBook を AppleScript で操作しましょうというこの試み。この手の情報って探してみてもなかなか見つからなかったりします。

「システム環境設定」の「共有」の「サービス」タブにある「リモート AppleEvent」にチェックを入れたらこれだけで Mac を遠隔操縦することができます(要注意。セキュリティについてはここでは触れません)。では、スクリプトを書いて試してみます。

通常、Finder のスクリプトを書くときは、次のようにして Finder を指定します。

tell application "Finder"
    (* ここに処理を記述 *)
end tell

リモート AppleEvent で接続された Mac(ホスト)の Finder を操作するには、次のように Finder を指定します。

application "Finder" of machine "eppc://Mac の名前"

ホスト側の Mac の URL 指定が追加されます。「eppc://」は、リモート AppleEvent が利用するプロトコルです。「Mac の名前」は、「システム環境設定」の「共有」で設定したコンピューターの名前になります。iBook には、iBook800 という名前を付けました。これは、「共有」の「コンピューター名」の下の「ローカルサブネット上のほかのコンピュータから、iBook800.local でこのコンピュータにアクセスできます」というように書かれている「iBook800.local」になります。Bonjour で使われるコンピューター名になるのですが、同じものをリモート AppleEvent でも利用します。

先ほどの Finder の指定は、次のようになります。.

tell application "Finder" of machine "eppc://iBook800.local"
    (* ここに処理を記述 *)
end tell

なんらかの処理を記述して構文確認を行うと、ホスト(iBook)の認証ダイアログが表示されます。構文確認を行うだけでも認証が必要なのですね。それではいささかめんどうなので、通常は using terms from を使ってクライアント側(iMac)のアプリケーションの用語辞書を使って構文確認を行います。

using terms from application "Finder"
    tell application "Finder" of machine "eppc://iBook800.local"
        version
    end tell
end using terms from

これで構文確認はできます...?できないですね。思いっきり認証ダイアログが表示されます。これを回避するためにホスト側を変数に入れてしまいます。

set remoteFinder to application "Finder" of machine "eppc://iBook800.local"

using terms from application "Finder"
    tell remoteFinder
        name of startup disk
    end tell
end using terms from

これでクライアント側(iMac)の Finder を使って構文確認ができます。では、実行してみましょう。

...また、認証ダイアログが表示されましたね。このダイアログに「キーチェーンに追加しますか?」というチェックボックスがあるのでホスト(iBook)のユーザー名とパスワードを入力してキーチェーンに追加しておきます。

認証は、キーチェーンに追加して全て解決、というわけには(なぜか)いきません。たとえば、AppleScript を終了して再度スクリプトを実行するときに先ほどの認証ダイアログが表示されます。どうしてでしょう?安全のため?ともかく、これでは認証ばかりで面倒です。次は、これを解決してみましょう。

リモート AppleEvent (1)

複数台の Mac を持っているとやってみたくなるじゃないですか。AppleScript で他の Macintosh を操縦って。そんなことないか?

AppleScript を使い始めたときからやってみたかったのです。が、複数台の Macintosh を持っていないし、セキュリティ的にどうなのかもよく分からない。今でも分かっていません。その辺りは調べていないので、これを読んでも不安な方は利用しない方がいいと思います。

ともかく、複数台の Macintosh を持っているのだから、試してみようと調べてみました。これが大変だったりします。で、防備録として。まだ、よく分かっていないのでこうできるとか、無線 LAN でとかインターネットを利用してこうできるとかの突っ込みもあるかと思いますが、掲示板にでも書いておいてもらえると嬉しいです。

まず、使う Mac は、有線 LAN でローカル接続です。インターネットに接続していません。単純に Ethernet でつないでいます。Mac は、iBook G3 800 GHz(Mac OS X 10.3.9) と iMac G5 2 GHz(Mac OS X 10.4.2)です。iMac から iBook を操作します。Ethernet をつないだらほとんど勝手に両者はつながります。これでファイル共有などができるようになります。どちらの Mac も管理者として起動しているとします。

つながったら操作される Mac(iBook)のシステム環境設定の「共有」の「サービス」タブを開き、「リモート AppleEvent」にチェックを入れます。ついでにコンピュータの名前も設定しておきます。ここでは、iBook800 にしておきました。これで iMac 側から iBook を AppleScript で操作できるようになります。設定は至って簡単。セキュリティはどうなのか知りませんが。

ここまでが準備段階です。