おっぱいスクリプト with AppleScript

ゆけ。リビドーの赴くままに。

...もう旬が過ぎた気もするし、三連休が終わって明日から仕事なんだろうけど AppleScript によるおっぱいスクリプトの実装を。

他の言語ではどのように実装されているか、といったことを比べながら読むと AppleScript の長所や短所がよく分かる気がします。

最大の違いはどの言語も最初からライブラリが豊富だったり、追加できたり...と。AppleScript は他の言語がライブラリを利用して実装している部分をすべて自分で作らなければだめなのです。ゆえに、コードが長い...。

なんの奇もてらっていないので、AppleScript をこれから覚えるんだ!といった中学、高校生以外にはなんの面白みもないものになっていますのであしからず。

Yahoo の検索 API を使っているので、Yahoo!デベロッパーネットワーク で登録して、アプリケーション ID を取得しておいてください。

Script Editor で開く

property APP_ID : "ここに Yahoo のアプリケーション ID を入れてちょ"
property API_URL : "http://search.yahooapis.jp/ImageSearchService/V2/imageSearch"
property SEARCH_WORD : "おっぱい"

on run
    main()
end run

on main()
    set my SEARCH_WORD to text returned of (display dialog "Enter search word:" default answer SEARCH_WORD with icon 1)
    set dataFolder to choose folder

    set pageCount to 1
    set downloadCount to 1

    repeat until pageCount is greater than 20
        set queryList to {{"appid", APP_ID}, {"query", SEARCH_WORD}, {"results", "20"}, {"adult_ok", "1"}, {"format", "jpeg"}, {"site", "tumblr.com"}, {"type", "any"}, {"start", ((pageCount - 1) * 20 + 1) as text}}

        set theURL to my makeQuery(queryList)
        set xml to my urlopen(API_URL & "?" & theURL)
        set xmlDocument to my openXML(xml)
        set root to my getFirstNode(xmlDocument)

        if my getNodeName(root) is "ResultSet" then
            repeat with thisItem in my getElementsByTagName("Result", root)
                set imageURL to my getFirstNodeTextByTagName("Url", thisItem)
                my downloadFile(imageURL, dataFolder)
                set downloadCount to downloadCount + 1
            end repeat
        end if
        set pageCount to pageCount + 1
    end repeat
end main

on encodeURL(theText)
    try
        return do shell script "python -c \"import sys,urllib; print urllib.quote(sys.argv[1])\" " & quoted form of theText
    on error mes number num
        return {num, mes}
    end try
    return theText
end encodeURL

on urlopen(thisURL)
    try
        set theResult to do shell script "curl " & quoted form of thisURL
    on error msg number num
        set theResult to {msg, num}
    end try

    return theResult
end urlopen

on downloadFile(fileURL, downloadFolder)
    do shell script "cd " & quoted form of (POSIX path of downloadFolder) & ";curl -O -L " & quoted form of fileURL
end downloadFile

on makeQuery(queryList)
    set theList to {}
    repeat with thisItem in queryList
        set thisItem to {item 1 of thisItem, my encodeURL(item 2 of thisItem)}
        set end of theList to my join(thisItem, "=")
    end repeat

    return my join(theList, "&")
end makeQuery

on join(theList, delimiter)
    tell (a reference to text item delimiters)
        set {tid, contents} to {contents, delimiter}
        set {theText, contents} to {theList as text, tid}
    end tell

    return theText
end join

on openXML(theFile)
    tell application "System Events"
        delete every XML data
        set xmlDocument to ""
        try
            set xmlDocument to contents of XML file theFile
        on error msg number num
            if num is -1728 then
                if (class of theFile) is text then
                    set xmlDocument to make new XML data with properties {text:theFile}
                else
                    return {num, msg}
                end if
            else
                return {num, msg}
            end if
        end try
    end tell

    return xmlDocument
end openXML

on getFirstNode(xmlDocument)
    tell application "System Events"
        return first XML element of xmlDocument
    end tell
end getFirstNode

on getNodeName(node)
    tell application "System Events"
        return name of node
    end tell
end getNodeName

on getElementsByTagName(tagName, node)
    tell application "System Events"
        if exists (XML elements of node whose name of it is tagName) then
            return XML elements of node whose name of it is tagName
        else
            return missing value
        end if
    end tell
end getElementsByTagName

on getFirstNodeTextByTagName(tagName, node)
    tell application "System Events"
        if exists (XML elements of node whose name of it is tagName) then
            set firstNode to my getFirstNodeByTagName(tagName, node)
            set nodeText to value of firstNode
            try
                nodeText
            on error
                return ""
            end try
        else
            return ""
        end if
    end tell
end getFirstNodeTextByTagName

on getFirstNodeByTagName(tagName, node)
    tell application "System Events"
        if exists (XML elements of node whose name of it is tagName) then
            return (first item of (XML elements of node whose name of it is tagName))
        else
            return missing value
        end if
    end tell
end getFirstNodeByTagName

140 行ほどですか。長いですね。長いです。このハンドラでまとめている部分のほとんどが、他の言語ではライブラリとして用意されていたりします。ファイルのダウンロードすら現在では OSAX がなくなり、AppleScript では処理できないですからね。

健全な青少年も利用できるように検索語句は利用者が入力できるようにしています。

改良できる部分は多々あると思います。現状、リクエストに対しエラーが返ってきたら無視しているので、結果が返ってくるまでリクエストを繰り返してもいいと思います。また、画像の大きさを調べて小さいものはダウンロードしないといったことをしてもいいかも。

では、また。

AppleScript でクロージャ

クロージャがなにかってことはイマイチよく分かっていないのだけど。

Python クックブック 第2版を読んでいて、載っていたスクリプトを AppleScript で書き直したら、動いたって話なんだけど。JavaScript ほど多彩なことができるわけではないのだけど。

まぁ、どこでどのように使うのかというギモンは残るんだけどね。

AppleScript の場合、関数(ハンドラ)の中に関数(ハンドラ)は作れない。これはご存知だと思います。しかし、スクリプトオブジェクトなら作ることができます。

Script Editor で開く

on makeObject(i)
    script MyObject
        property counter : i

        on countUp()
            set counter to counter + 1
        end countUp

        on getCounter()
            my counter
        end getCounter

        on run
            countUp()
        end run
    end script
end makeObject

set theObject to makeObject(0)

tell theObject
    run
    display dialog getCounter()
    run
    display dialog getCounter()
end tell

単純な例ですが、実行するたびにカウントを行うスクリプトオブジェクトです。makeObject ハンドラ実行時に引数を渡し、それが MyObject の属性に初期値として設定されています。これはこれで特に問題はないのですが、MyObject の属性 counter は書き換え可能です。

tell theObject
    run
    display dialog getCounter() -- 1
    run
    display dialog getCounter() -- 2
    set counter of it to 100 -- 値を書き換えてみる
    run
    display dialog getCounter() -- 101
end tell

スクリプトオブジェクトの属性は読み書き可能。これは、AppleScript では当たり前のことですね。では、次のように書き換えてみましょう。

Script Editor で開く

on makeObject()
    set counter to 0
    script MyObject
        on countUp()
            set counter to counter + 1
        end countUp

        on getCounter()
            return counter
        end getCounter

        on run
            countUp()
        end run
    end script
end makeObject

set theObject to makeObject()

tell theObject
    run
    display dialog getCounter() -- 1
    run
    display dialog getCounter() -- 2
    try
        set counter of it to 100 -- 値を書き換えてみる
    on error msg number num
        error number num
    end try
    run
    display dialog getCounter() -- 3
end tell

makeObject ハンドラ実行時の引数をなくし、MyObject の属性 counter を makeObject ハンドラ内のローカル変数にしてみました。ハンドラ実行時のローカル変数がハンドラ実行後も保持され、スクリプトオブジェクト内から参照可能です。が、スクリプトオブジェクトの外から counter の値を変更することも参照することもできません。

もう少し分かりやすく書くと以下のようになります。

Script Editor で開く

on DataObject(theKey, value)
    script
        on getKey()
            return theKey
        end getKey

        on getValue()
            return value
        end getValue
    end script
end DataObject

set theData to DataObject("id", "someone")
theData's getKey() -- "id"
theData's getValue() -- "someone"

変数 value や theKey にアクセスするにはハンドラを利用する以外ありません。もちろん、グローバル変数を利用すると話は別ですが(または、スクリプトオブジェクト内に setter を用意するとか)。

と、にハンドラ内のローカル変数が保持されることは分かったのですが、これがクロージャなのかといわれるとよくわからなかったりする。以下のようにしておけば、スクリプトオブジェクトの初期化処理を複数回呼び出すことを防いだりできるかな?

Script Editor で開く

on makeObject()
    set instance to missing value
    script MyObject
        on init()
            if instance is missing value then
                (* ここに初期化処理 *)
                -- ハンドラのローカル変数に自身を割り当てる
                set instance to me
            else
                -- 初期化されてるよ
                display dialog "Initialize OK"
            end if
        end init

        on greeting()
            display dialog "Hello"
        end greeting
    end script

    init() of MyObject
    return instance
end makeObject

set x to makeObject()
init() of x
greeting() of x

init ハンドラ自体を呼び出せないようにしたいけど、そこまで求めるのは無理があったりなかったり。

TextEdit.app でアウトライン

バージョンが上がるごとに地道な改良が加え続けられている TextEdit.app。ちょっとした書類なら TextEdit.app だけで十分ということも多い。Mac OS X 10.7 に付属している TextEdit はついに縦書きにも対応した。

TextEdit を使ってどのような表現ができるかは、ちゃんと知りたいテキストエディット.appとリッチテキストの使い方 - ザリガニが見ていた...。に詳しい。

だけど、(個人的には)一つだけ問題があった。

それはアウトラインについて。袋文字ともいうようだけど、TextEdit ではアウトラインにした文字列の中の色を指定することができない。

TextEdit_Outline_001.jpg

このように通常は現在の文字色でアウトライン化され、文字の内側の色は白以外指定することができない。袋文字 - Wikipediaなのだからこれでいいともいえるのだけど、アウトラインの外側と内側の色の両方を個別に指定したい。

いろいろと調べたのだけど、TextEdit.app で作成する方法が見つからない。こういう要望って少ないのでしょうか?

AS Hole(AppleScriptの穴) By Piyomaru Software » Keynote上でコピーされたテキストオブジェクトの内容をTextEditで解析してIllustratorで白フチ文字を作成してKeynoteにペースト v2 » Blog Archiveといった方法は見つかったのだけど、これはなかなか敷居が高い。そもそも Illustrator 持ってないし。

...はたと気がつく。RTF なんだから、中身のデータそのものをいじってしまえばいいのでは?そもそも RTF の中身なんて文字列なんだし。

ようやく探し当てたのが Attributed String Programming Guide: RTF Files and Attributed Strings

さすが Apple。ちゃんと用意していました。上記の文書を読むと、strokewidth が文字列をアウトライン化するのに使われている制御コード。この strokewidth にマイナスの値を適用すれば文字列の内側にも色を付けられるようです。実際に TextEdit.app で作成した RTF ファイルをテキストエディタで開き、strokewidth の値をいじっていたらできました。

TextEdit_Outline_002.jpg

「書式」メニューの「スタイルをコピー」、「スタイルをペースト」メニューを使えば、他の Cocoa アプリケーションでも同じスタイルを使い回すことができます。例えば、Keynote や Pages や Numbers。もちろん Apple のアプリケーションでなくても使えます。

しかし、RTF ファイルをテキストエディタで開いて中身の制御コードをいじるというのはなかなか面倒なもの。そこで、アウトラインの内側の色と外側の色を指定して RTF ファイルをつくるスクリプトを。

Script Editor で開く

on run
    set template to "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1138\\cocoasubrtf470
{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;$innerColor;$outerColor;} \paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural
\f0\fs192 \cf2 \outl0\strokewidth-60 \strokec3 Outline Text}"
    -- cf number = character color
    -- strokec number = stroke color

    display dialog "文字の内側の色を選択" with icon 1 giving up after 3
    set innerColor to my color2RTFColor(choose color)
    display dialog "文字の外側の色を選択" with icon 1 giving up after 3

    set outerColor to my color2RTFColor(choose color)

    set template to my substitution(template, "$innerColor", innerColor)
    set template to my substitution(template, "$outerColor", outerColor)

    set theFile to (path to desktop as text) & "Outline Text.rtf"

    my writeFile(theFile, template)

    tell application "Finder" to open file theFile using (path to application "TextEdit")
end run

on color2Hex(colorList)
    repeat with thisColor in colorList
        set contents of thisColor to ((thisColor as integer) * (255 / 65535)) as integer
    end repeat

    return colorList
end color2Hex

on color2RTFColor(colorList)
    color2Hex(colorList)
    set {r, g, b} to colorList
    set theList to {"\\red" & r as text, "\\green" & g as text, "\\blue" & b as text}

    return (theList as text)
end color2RTFColor

on substitution(theText, fromText, toText)
    tell (a reference to text item delimiters)
        set {tid, contents} to {contents, fromText}
        set {theList, contents} to {every text item of theText, toText}
        set {replacedText, contents} to {theList as text, tid}
    end tell

    return replacedText
end substitution

on writeFile(theFile, theText)
    try
        set fh to open for access file theFile with write permission
        set eof fh to 0
        write theText to fh starting at eof as «class utf8»
        close access fh
        return true
    on error eMsg number eNum
        try
            close access fh
        end try
        return false
    end try
end writeFile

ぶっちゃけ文字列を置き換えているだけだったりしますが。

トラブル続きの Lion さん

なんだかなぁ...。最近、うちの MacBook(Late 2007) はトラブル続きです。

この前はプリンタのジョブが原因でスリープしなくなりましたが、今回は WiFi につながらない。なにが原因か分からない。直った現在もなにが原因か分からない。

ことの起こりは、メニューバーにある WiFi をいったん「切」にして MacBook をスリープさせたことから始まりでした。

MacBook を利用するためにスリープを解除し、メニューバーから WiFi を「入」にしてもいっこうにつながらない。それどころか、見慣れない文字が書かれている。『ハードウェアがありません』と。なんのことやら分からない。

MacBook を再起動しても直らない。そういえば、先月は WiMAX の更新月だったような。もしかしたら、更新を怠っていたかな?と思うも、iPhone は WiFi 経由で WiMAX につながっている。

とりあえず「Console.app」を立ち上げログを表示させながら、WiFi の「入」を行う。すると、『failed to set airport power state』などと記述される。この情報をもとに再度、検索。すると、同じ原因の情報が見つかる。

このページの解決法を読んだとき、眉唾かと思いましたが直りました。解決法は、Mac を再起動するときに表示されるダイアログの「再ログイン時にウィンドウを再度開く」のチェックを外しておくだけです。

quit_dialog.png

これだけで元に戻りました。なぜかは分からないけど、おそらくその辺りでナニか不具合があるのでしょうね。

眠らない MacBook

最近 MacBook の眠りが悪いとお嘆きのあなた。そんなあなたにお勧めなのが、これ。

って、私のことなのだけど。うちの MacBook(Late 2007) は、Lion を載せて元気に働いています。

と言いたいところなのですが、最近 MacBook の蓋を閉めてもスリープしない。AppleScript で命令してもスリープしない。どのようにしてもスリープしない...。MacBook(Late 2007) では Lion さんを動かすのに非力でしたか...。

まさか、非力だろうという曖昧な結論で終わらせるわけにもいかない。で、検索してみると、同じような症状で悩んでいる人が多いみたいで...。

最初に pmset で現状を確認したのですが、このときは原因が分からず。このときに気がついていたら、いろいろな苦労をすることもなかったのですが。再起動や PRAM や PMU のリセット、アクセス権の検証にディスクの検証、Console.app を起動してログの調査...とりあえず、できることはやってみました。

しかし、pmset で表示される現在の設定に原因が書かれていました。結論から書くと、スリープを阻害する何らかのプロセスがあったわけです。

$ pmset -g
Active Profiles:
Battery Power       -1
AC Power        -1*
Currently in use:
 womp       0
 autorestart    0
 halfdim    0
 sms        1
 panicrestart   157680000
 hibernatefile  /var/vm/sleepimage
 networkoversleep   0
 disksleep  10
 sleep      0 (imposed by 16)
 hibernatemode  3
 ttyskeepawake  1
 displaysleep   25
 acwake     0
 lidwake    1

sleep が 0 になっていて (imposed by 16) となっています。プロセス ID 16 が邪魔してますってことらしいです。

最終的に行き着いたのが、Swish Movement: Update: Lion sleep woes solved。ここに書かれている通りにプロセスを調べると、スリープの邪魔をしていたのがプリンタのジョブだということが判明。

何日か前に印刷をしたもののプリンタが繋がれていない状態だったので、エラーになっていました。このジョブを削除したところ、ちゃんとスリープするようになりましたと。

しかし、なんらかのプロセスによりスリープができなくなるなんて...。しかも、これバッテリ駆動だとこの問題が発生しない。バッテリ駆動だと蓋を閉めることでスリープするのです。電源がつながっているときだけ、スリープしない。気がつきにくいことこのうえない。

今回はプリンタのジョブが邪魔をしていたってことで、問題は解決したのですが、簡単には解決しない人も多数いるようで...。みなさんの問題が解決することを祈っております。

iPhone アプリケーションの URL スキームを調べる

Launch Center という iPhone アプリケーションがあります。

iOS 5.1 になって iPhone の設定を開けなくなったのは悲しい出来事でしたが、それでも少ない手間で目的のアプリケーションを起動することができるなかなか便利なアプリケーションです。いまさらここで詳しい使い方を書くのもあれなので、いくつか参考になるところを。

このアプリケーションはいわゆるランチャーなのですが、起動することができるアプリケーションは URL スキームを持っているかどうかで決まります。 Launch Center で対応しているアプリケーションもありますが、それ以外のアプリケーションは URL スキームを持っているかどうか調べないと分からない。

調べる方法はいくつかありますが、なかなか面倒。こういうものは人力でするものではありません。

iPhone のアプリケーションはバックアップ先の Mac に保管されていると思います。この保管されているアプリケーションの中にある、Info.plist というファイルを調べると URL スキームを持っているかどうか、持っているならどういう文字列か、ということはすぐに分かります。

iPhone のアプリケーションは実際のところ Zip ファイルで拡張子 ipa を zip に変更すれば、そのまま解凍できるというのはよく知られた話です。が、これらのアプリケーションのファイル名を変えて、解凍し、Info.plist を開き、目的の文字列を探し出すのは面倒な作業です。

これらの作業(Zip に変更し、解凍)を行うスクリプトをぴよまるソフトウェアさんが公開していますが、ここまでするのも大袈裟です。

ようは Info.plist 内の特定の文字列を探し出すだけです。アプリケーションのすべては必要ありません。どうすれば、Info.plist だけを抜き取ることができるか...。AppleScript だけでは Zip ファイルを解凍せずに目的のファイルを抜き出すことはできません。

でも、python は標準で入っているよな...。python には zipfile があるよな...。

なら、両者を組み合わせればいいだけで、こういうことこそ AppleScript の得意とするところ。

アプリケーション形式の AppleScript でパッケージ内に python スクリプトを配置しています。使い方は至って単純で iPhone アプリケーション(拡張子 ipa。複数可)をこのアプレットに放り込むだけ。もしくは、アプレットをダブルクリックで起動し、拡張子 ipa のファイルを選択するだけです。

処理が終了すると、デスクトップ上に「URL Schemes.csv」というファイルを作り、その中に URL スキームを書き出します。あとは、テキストエディタで開くなり、CSV ファイルなので Numbers や Excel で開くなりしてください。

ま、いつものごとく特別にエラー処理はしていないのでご利用は、ご自身の責任でお願いします。

AppleScript Editor で作る Cocoa アプリケーション

Mac OS X 10.7 を導入したのがそもそも遅かった...というのもあるのですが、旬の話題はそろそろ次の OS ですか。そうですか。そうですか。

そんな話題で盛り上がっている中、AppleScriptObjC...略して ASOC です。

AppleScriptObjC...っていうのはいったいなんなのか?

というところから話を始めますが、そもそも AppleScript というのは Mac を使う上で面倒な『日々の同じ作業を自動化する』ために生まれたプログラミング言語。いわゆるバッチ処理ですね。

Mac で作業するっていうことはいろいろなアプリケーションを扱うってことで、Mac での作業を自動化するということは、いろいろなアプリケーションを自在に操る必要があるわけです。その『アプリケーションを自在に操る』ために用意されたのが AppleScript です。

大雑把にいってしまうと、AppleScript というのはいろいろなアプリケーションを繋ぎ合わせるためのプログラミング言語。グルー言語(糊言語)なんていったりしますが、AppleScript はまさしく糊でいろんなアプリケーションを連携させることに長けています。

AppleScript は年月を積み重ねることで様々な機能が付加され続けてきましたが、シェルスクリプトと連携することができるようになったおかげで Perl や Python、Ruby などのスクリプト言語との連携もでき、Safari を通じて JavaScript を利用することができるようにもなりました。グルー言語の面目躍如といったところでしょうか。AppleScript 単体ではできない処理もアプリケーションや他のスクリプト言語の力を借りて処理が行えたりします。

do shell script 命令を利用することで他のスクリプト言語を活用することはできたのですが、Mac OS X の Cocoa フレームワークの機能を利用することはできませんでした。が、Mac OS X 10.6 から追加された ScriptingBridge というフレームワークを利用することにより、ついに AppleScript からも Cocoa の機能を利用することができるようになったのです。

Mac OS X 10.6 では Xcode でしか AppleScriptObjC のアプリケーションを作ることができませんでしたが、Mac OS X 10.7 からは AppleScript Editor で Cocoa アプリケーションが作れるようになりました。

もう、AppleScript なんでもアリです。というか、こんな面白いオモチャいじられずにおられるものか。

では、さっそく AppleScript Editor で Cocoa アプリケーションを作ってみましょう。

AppleScript Editor を起動し、「ファイル」メニューの「テンプレートから新規作成」メニューにある「Cocoa-AppleScript Applet.app」をクリックします。

template_menu.jpg

すると、保存されているテンプレートをもとに新しいアプレットが作成され、編集が行えるようになります。

テンプレートからアプレットが作成されたら、すでに Cocoa の機能を利用できる環境が整っています。おもむろに以下のコードを記述してみましょう。

tell current application's NSDistributedNotificationCenter's defaultCenter()
    addObserver_selector_name_object_(me, "update:", "com.apple.iTunes.playerInfo", missing value)
end tell

on update_(aNotification)
    set userInfo to aNotification's userInfo
    if (|Player State| of userInfo) as text is "Playing" then
        tell me to activate
        display dialog (|Name| of userInfo as text) with title (|Artist| of userInfo as text) with icon 1 buttons {"OK"} default button 1 giving up after 5
    end if
end update_

on quit
    tell current application's NSDistributedNotificationCenter's defaultCenter()
        removeObserver_(me)
    end tell

    continue quit
end quit

Objective-C のプログラムを AppleScript のスクリプトにどのように変換すればいいかは、AppleScriptObjC Release Notes に書かれています。

スクリプトは iTunes からの通知を受け取って曲の変わり目にその曲の情報を表示するというものです。

実行は、通常のスクリプトと同じように「スクリプト」メニューの「実行」を選択すればいいのですが、選択するとシートが表示されます。

run_application_sheet.jpg

ここでは必ず「アプリケーションを実行」を選択してください。「スクリプトを実行」を選択すると、通常の AppleScript として実行され、Cocoa の機能は利用できません。

シートの表示が煩わしい場合は、「スクリプト」メニューの「アプリケーションを実行」を選択すればシートは表示されず、すぐに実行されます。

スクリプトはアプリケーションとして実行されるので、明示的に終了させないといつまでも起動したままになります。通常のアプリケーションと同じようにアプリケーションメニューの「終了」を選択します。

アプリケーションとして実行されるということは AppleScript Editor でのデバック機能は利用できないということです。結果や実行途中のイベントも取得できません。これが困ったところで、現在のところデバックするには log 命令を利用して Console.app にログを表示するぐらいしか方法がありません。

ほかの注意点としては、display dialog 命令で NSString を表示する際には明示的に型変換を行うといったことがあげられます。これは、NSString だけのことではなく、Cocoa のクラスを AppleScript で利用する際にはこの型の変換を常に意識しておく方がいいです。

また、current application 経由で Cocoa の機能を呼び出しているため、current application を省略することもできません(短く記述したいなら、my でも it でも可)。

総体的には手っ取り早く Cocoa の機能を使ったアプリケーションを作るには選択肢として有りだと思うのですが、デバック機能が log 命令ぐらい(ファイルに書き出したり、ダイアログも使えますが)しかないのが致命的です。GUI の構築に手間がかかるというのも、その辺りを期待していた人には問題になるかも。

Xcode で作った ASOC アプリケーションのコードをそのまま流用できないというのもなんだかなぁというところです(スクリプトそのものはコピーアンドペーストで利用できます。Xcode はスクリプトをテキストファイルとして保持しているけど、AppleScript Edito ではコンパイル済みのスクリプトファイルでないと利用できないので)。

とりあえず、Cocoa の機能を呼び出せることは分かったけど、これを使ってなにができるか?、どこまで利用できるのか?といったことが問題になってくると思います。例えば、GUI を利用したいとか、クラス間の連携だとか...。その辺りのことは、また次回にでも。