AppleScriptObjCを使ったアプリケーション製作の概要

 OS Xは、アプリケーションを作るための言語としてもAppleScriptが使えます。
 以前はAppleScript Studioという仕組みがありましたが、Mac OS X10.6からはAppleScriptObjC(以下ASOC)という仕組みに切り替わりました。

 一応このサイトは、AppleScriptのサイトなので、AppleScriptObjCについても書いておこうかなということで、ざっと調べて書きました。
 なお、このページはMac OS X10.10(Yosemite)の内容で書いています。
 使用したXcodeはバージョン6.1です。

基本情報

 XcodeでApplicationを開発する際の選択肢としてAppleScriptが用意されているという話で、特別な開発用アプリケーションが存在するわけではありません。
 以前からXcodeはJavaとかRubyやPythonを開発言語として使用できる時期があったんですが、 わりと用意したはいいけどサポートもなくほったらかしのまま終了、というパターンに陥っています(注1)
 AppleScriptに関しても、以前はAppleScript Studioという「インタフェース部品をAppleScriptのオブジェクトとしてそのまま使える」という素敵な環境があったんですが、やはりこれもほったらかしのまま終了の憂き目に遭っています。
 今回調べたASOCもOS X10.6から存在するものの「Mac OS X10.10では消える」とか噂されたりしてて、非常に危うい状態の環境といえます。

 Appleが出している日本語の情報はありません。デベロッパーたる者、英語が読めて当然です。私はあまり読めませんけどね!
 リリースノートはAppleScriptObjC Release Notesです。
 この資料のTranslation Guideのところの表を見れば、Objective-CとAppleScriptを両方とも使える人なら、ざっくりとした内容は掴めると思います。
 と、書いたところで気づいたんですか、そういう人ってもうここで書いてる程度のことはチェック済みですよね…。
 つまりもう完全に自分用のメモですね、これ。

最初の一歩

 XcodeをAppStoreからダウンロードしてインストールが完了したところで、おもむろに起動、そして最初に出る「プロジェクトのテンプレート」の選択から、[Other]の中にある「Cocoa-AppleScript」を選びます(注1)
 そして…といちいち説明するのも面倒だし、読むのも面倒だと思うので、次のムービーを見てください。
 AppleScriptObjC Chapter 3 - YouTube
 ほとんどマウス操作だけでグイグイとアプリケーションができあがっていく様子にトキメキますね!
 AppleScriptObjC Resourcesで紹介してあるAppleScriptObjC Exploredという書籍の解説ムービーです。
 この本は、大変評判がいいのですが私は読んだことありません。ちなみに日本語訳はありません。そのうち買うかも。

 さらに、こちら1時間を超える大作ですが、それだけの時間で概要を掴めると思えば手っ取り早いといえるでしょう、これも見てみましょう。
 Giving your AppleScripts a Face Lift with AppleScriptObjC - Ben Waldie - YouTube

 ほぼ理解したような気になれますね!!(注2)

クラスはスクリプトオブジェクトに書きかえ

 プロジェクトを作ると、AppDelegate.applescriptというファイルがあります。
 そこを見ると、Objective-Cで開発する際のクラスはAppleScriptのスクリプトオブジェクトに置き換えられてます。
 以下のような感じです(注1)

script AppDelegate
	property parent : class "NSObject"
	
	-- IBOutlets
	property theWindow : missing value

…

end script

 継承の親は、propertyを使いproperty parent : class "NSObject"(注2)といった形で指定されています。

 アプリケーションに含まれるオブジェクトは、同じくpropertyを使いproperty theWindow:missing valueといった感じに初期化しておいて、後でマウスを使ってGUI部品と接続します。
 ウインドウだけでは寂しいので、MainMenu.xib(注3)を選択し、ウインドウにボタンを追加してみます。
 Xcode6.1だと右下のペインに(◯と□を組みあわせた)六文銭のようなアイコンがあり、それを押すとGUI部品が表示されるので、そこからボタン(たくさんありますが、NSButtonならどれも初期値が異なるだけの同じものです)を選んでウインドウにドラッグして配置します。

 そして AppDelegate.applescript の theWindow が設定してある行に続けて、次のように書きます。
 これで、ボタンオブジェクトとそれへの参照を格納するプロパティ変数の準備ができました。

	property myButton:missing value

 MainMenu.xibファイルを見るとGUI部品が置いてある作業領域の左に、アイコンが縦に並んでいるDocument Outlineの領域があり、そこの青い立方体の一つがAppDelegateです。
 AppDelegateを選択して、右上のインスペタクを確認します(注4)。インスペクタには色々とGUI部品の情報が表示されますが、ここでは◯と→を組み合わせたアイコンを選択して Connections Inspector表示にします。
 インスペクタを見ると、[Outlets]にpropertyで設定したmyButtonを確認できます。
 MainMenu.xibのウインドウにボタンを配置し、[Outlets]にあるmyButton○からボタンまで線を引っ張って接続し、myButton - ✖︎ Button◉の状態にします。
 これで、スクリプト中でボタンのプロパティなどが取れるようになりました。
 このあたりムービーで見たとおりですが、バージョンによって相当異なったビジュアルになっていると思うので、そこはセンスで!!

 フレームワークをインポートしたい場合はuse(注5)を使い、use framework "フレームワーク名"という感じに指定するようです…たぶん。

Objective-Cのメソッドの書きかえ方

 Objective-C(API)のメソッドは、:で引数を区切る方式が使われています。
 これがAppleScriptでもうまく使えるように、特別な書式がAppleScriptに導入されました(注1)
 AppleScriptで書く場合もObjective-Cと同様な「クラス名's メソッド:引数a ラベル1:引数b ラベル2:引数c…」みたいな書式になります(注2)

 メッセージを受け取るハンドラは、以下のように書きます。ハンドラ名は適宜決めていいのですが、メソッド呼び出しと同様に最後を:で止めて引数を書く書式を使います。

   on clickButton: sender
       log "Clicked!!"
   end

 この:区切りの書式で書いておくと、Xcodeはメッセージを受け取るハンドラと判断し、App Delegateインスペクタの[Recieved Actions]にそのハンドラ(ここではclickButton)を表示します。
 このclickButton:○からウインドウに配置したボタンへ接続して、clickButton:-✖︎Button◉の形にします。
 逆に、Buttonのインスペクタの[Sent Actions]にある[selector]からApp Delegateに接続して、表示されたハンドラのリストの中から[clickButton]を選び、clickButton:-✖︎AppDelegate◉の形にしても、同様にメッセージの経路の接続ができます。

縦棒で衝突を回避

 例えば、setはAppleScriptでは最頻出の識別子ですが、ObjC側のメソッドとしても割と使われていて、両者が衝突します。
 そこで、ObjC側のメソッドは縦棒で括って |set| とし、区別する必要があります(注1)
 非常に格好悪いし読みにくいんですが、最初から混在して使う予定で設計されたわけではないので、致し方ないというところ。

 AppleScriptの予約語は、次のようなものがあります。
about above after against and apart from around as aside from at back before beginning behind below beneath beside between but by considering contain contains contains continue copy div does eighth else end equal equals error every exit false fifth first for fourth from front get given global if ignoring in instead of into is it its last local me middle mod my ninth not of on onto or out of over prop property put ref reference repeat return returning script second set seventh since sixth some tell tenth that the then third through thru timeout times to transaction true try until where while whose with without
 Xcodeのエディタ上では予約語に色が付くので、「あ、これはぶつかる」と事前にわかります。

 困ったことに、AppleScript全体の予約語だけではなく、アプリケーション毎に設定された用語とも衝突するので、上記単語以外でも衝突の可能性があります。
 boundsとかpositionとか、そういうプログラミングに使われがちな単語が当然衝突します。
 ObjCのメソッドを縦棒で括ることによる弊害は、コードが見ずらくなること以外はないようです。
 なので、怪しそうならとりあえず縦棒で括って|bounds|と書いてしまう、というのがよさそうです。

さて、その先は

 検索して出てきたAppleScriptObjCの使い方のページを適当に並べました。
 とりあえず、導入とアプリケーションのビルドの部分までは以下のサイトをチェックすれば、いける感じです。

 あと、Mac OS X Automationのサイトは要チェック。

 もうこれから後は、AppleScriptもObjective-Cも変わりありません。
 それっぽいGUI部品を配置して名前をチェックして、Xcodeのヘルプで検索して、という感じでGUIは使えるようになるかと思います。
 GUIでない部分は、Appleのサイトで公開されているものと同じものが、Xcodeのヘルプから見れるみたいなので、ひたすら読んで試してみる、の繰り返しということでしょうか。
 むしろ、Objective-C(やSwift)で使ったことがあるAPIをAppleScriptでも動くか試して使う、というような感じになるかもしれません(注1)

感想

 AppleScript StudioはAppleScriptがAppleScriptのままMacのアプリケーションを使えるように作ろうとして、しばらく開発してみて「よく考えたら、そんな労力を割く余裕はなかった、てゆーかまともにこれをサポートするのは辛すぎる」と気づいたプロジェクトだったと言えます。
 気づいてすぐ反省すればいいものの、「うまくやれてるふりして放置した挙句頓挫する」というAppleのお家芸を披露してくれちゃいました。

 Appleは理想的な環境を作ろうとして、実際は作れっこない砂のお城を詰んでは崩すということを良くやります。
 理想的なことを語るもんだから、最初は開発者もときめいて「Appleさんならやってくれる!!」とか興奮しちゃうわけですけど、まぁ無理なもんは無理ですよね(注1)

 AppleScriptObjCの場合、とにかく最小の労力でAppleScriptからOS X APIを使える方法を用意して、AppleScriptとして仕様を整えるとかしない、という割り切りで作られています。
 むしろ、上記の特に:区切りメソッドのように、APIのアクセス方法はObjective-C記法に近づけていて、AppleScript的には少々異様です(注2)
 その方が、OS X APIとAppleScriptでの書き方の2種類を覚える必要がないから、Objective-CとAppleScriptを両方使いたい人にとっても、今はAppleScriptだけ使っているけどObjective-C(やSwift)も使いたい、と思っている人にとっては楽という目算でしょう。
 実際、個人的にはもちろんAppleという大会社であっても、二種類のアクセス方法を管理(テスト)するのは困難であった、ということです。

 とはいえ今のところ、プレーンなままでは解決できない(あるいは解決策が冗長にすぎる)問題も多いようで、AppleScriptからはうまくアクセスできないAPIも多く存在しているようです。
 ASOCはOS X10.6から存在しているのに、イマイチこなれていない感は否めません。
 現状は、そのへんを吸収する拡張機能であるASObjCExtras.frameworkを追加しておく方が無難なようです。
 Objective-CのオブジェクトとAppleScriptオブジェクト間の変換メソッドなど、便利な機能が豊富に用意されています(注3)
 ASObjCExtrasでダウンロードできます。
 ダウンロードページのあるMac OS X Automationは準オフィシャルなサイトなので、まずまず信頼していいでしょう。いやむしろ何かとフットワークの鈍いApple本体より信頼できるかもしれません。
 日本語では、AS Hole(AppleScriptの穴) By Piyomaru Software » ASObjCExtras.frameworkで、かなり詳しく解説されています。

 MacはObject Pascal→C→C++→Objective-C→Swiftと言語を渡り歩き、API、CPU、主な開発環境の全てにおいて、激しい変化の荒波を越えてきています。
 そんなこともあってAppleの技術者は少々仕様が混沌としても気にしないし、実際Macアプリ開発者もその混沌を乗り越えているんで、割とみんな慣れちゃうもんだったりしますが…私は大抵挫折しています(笑)
 荒れ狂う環境の中、AppleScriptは20年以上生き残っているんですから、Mac用開発言語としては一番の老舗と言え、Macの延べ開発者数としてはAppleScripterが一番多いかもしれませんね。

 AppleScriptObjCとは直接関係ない感想になっちゃいましたが、ASOC自体はアプリケーションの制御自体を目的とするアプリケーションの開発には、なかなか便利そうです。
 display dialog程度のインタフェースではなく、いくつかチェックボックスとかプルダウンメニューとかつけたいな、って感じのものを作るにはいい感じに思えます。

 ここまでObjective-Cっぽくなってくると、アプリケーションの制御以外が目的なら、直接Objective-Cで書いた方が早い(速い)でしょうね。
 Objective-Cが@とか[]がやたら出てきて気持ち悪いという人も、Swiftという選択肢が出てきましたしね。