Mac OS X 10.6 では、Xcode 3.2 を使います。Mac OS X 10.6 から AppleScript Studio が deprecated になり、AppleScriptObjC を使うことになりました。簡単に言うと、AppleScript で Objective-C のクラスを書けるように、うまいこと対応を付けたものです。これによって、Automator の実行速度が上がったり、ユーザにとってはいいことずくめですが、問題は、今までの Automator アクションの作り方と大幅に変わってしまったことです。現時点では Google 先生が教えてくれる情報は、あまりアテになりません。Apple もドキュメンテーションをサボっていて、手探り状態です。
まず、知っておかないといけないのは、Xcode 3.2 が作ったテンプレートの違いです。Mac OS X 10.5 用のアクションは、以下のように、単に run ハンドラに input と parameters が渡されるだけでした。
on run {input, parameters}
-- Add your code here, returning the data to be passed to the next action.
return input
end run
これからは、myaction.script にはこんなコードが生成されます。
script myaction
property parent : class "AMBundleAction"
on runWithInput_fromAction_error_(input, anAction, errorRef)
-- Add your code here, returning the data to be passed to the next action.
return input
end runWithInput_fromAction_error_
end script
script 〜 end script は見慣れないブロックです。これは、Objective-C のクラス定義で、myaction というクラスを宣言しています。2行目の property parent の行は AMBundleAction を継承をしていることを宣言しています。これにより、NSObject → AMAction → AMAppleScriptAction → AMBundleAction → myaction という継承ツリーを持ちます。on runWithInput_fromAction_error_ 〜 end runWithInput_fromAction_error_ はメソッドの定義です。オリジナルのアクションは、runWithInput:fromAction:error: をオーバーライドして作るという形になります。
AppleScript しか知らなくて、ピンと来ない人は、まずは、以下のようにテンプレートを埋めましょう。
script myaction
property parent : class "AMBundleAction"
on runWithInput_fromAction_error_(input, anAction, errorRef)
-- Add your code here, returning the data to be passed to the next action.
set input to input as list
set output to {}
repeat with i in input
-- do something for i
end repeat
return output
end runWithInput_fromAction_error_
end script
これで、入力ファイルに対して、順番に何かをする、という処理が書けると思います。アクションの出力は、ここではファイルと仮定しますが、POSIX File の文字列を output のリストに詰め込んで返却すれば OK です。
パラメタの参照
パラメタは以前は run ハンドラの引数に渡されていました。これからは、AMBundleAction から継承した parameters() メソッドを使って、パラメタの値が入ったレコードを取得します。個々のパラメタには AMDefaultParameters (Info.plist にあります) に設定したキーでアクセスできます。例えば、foo というキーを持つパラメタは foo of parameters() でアクセスできます。ただし、取得した値は、as text や as number などで、型をきっちり指定してください。パラメタと GUI のバインディングなどは、これまでと同じなので省略します。
アクションのバンドル
アクションのバンドルの中のファイル (リソース) の参照には path to resource は使えません。これだと Automator.app のバンドルを参照してしまいます。AMBundleAction から継承した bundle() メソッドを使って、一旦 NSBundle オブジェクトを取得したあと、NSBundle のメソッドを使ってアクセスします。名前の衝突を防ぐために、縦棒 (|) で囲って |bundle|() とやるとアクションのバンドルオブジェクトが取得できますので、それに対して、pathForResource:ofType:等を使ってリソースのパスを取得します。具体的には、以下のようになります。
set action_bundle to |bundle|()
set aPath to action_bundle's pathForResource_ofType_("image", "tiff")
エラーの返却方法などは、まだよく分かっていません。この辺になにやら書いてありますが、NSNumber と NSString を NSArray に突っ込んで返してるけど、NSError を返却するんじゃないの? という疑問が…。この情報も古いのかもしれません…。