Archive for the 'Xcode' Category
AppleScriptObjC Exlorer 2で、編集中のScriptをすべて保存してXcodeの最前面の(アクティブな)プロジェクトをビルドして実行するAppleScriptです。
……なるべく1行で内容が分かるように心がけていますが、さすがになんのことやら分かりにくいので、説明します。
本ScriptはMac OS X 10.6.8+Xcode 4.1+AppleScriptObjC Explorer 2 2.2.1で作成。Mac OS X 10.7上でも動くはずです。
Xcode 4.0以降でAppleScriptObjCのサポートは「悲惨」のひとことに尽きます。インデントは狂うわ、構文確認時の各種ブロックの補完は行われないわ、AppleScript構文色分けがまったくきかないわで、生産性がダダ下り。AppleScript Studioの頃には、Mac OS X 10.5の頃まではなんとか構文色分けは維持されてきたものですが……。

さすがに、Xcode 4.x内蔵のテキストエディタに愛想が尽きて、AppleScriptObjC専用外部エディタである「AppleScriptObjC Explorer 2」をお買い上げ。Xcode上のファイル一覧でAppleScriptを選択した状態でコンテクストメニューを表示。「Open With External Editor」を実行してAppleScriptObjC Explorer 2でAppleScriptのテキストを編集させるようにしています。

これで、構文確認時の各種ブロック(ifブロックとかrepeatブロックとかtellブロックとか)の入力補完や、AppleScript構文色分けなどが利用できます。
ただ……Mac OS X 10.6/10.7ともに、Xcodeの外部エディタとして使用した場合に、AppleScriptObjC Explorer 2からはXcodeプロジェクトのビルドやら実行やらはできません(Mac OS X 10.7上でAppleScriptエディタ上と同様にAppleScriptObjCプログラムを単体で作成・実行できます)。
そこで、AppleScriptObjC Explorer 2側からXcodeのプロジェクトをビルド&実行するようにしてみたのが本AppleScriptです。
ただし、Xcode 4.x系のAppleScript対応機能は、いまだ実装の発展途上というか、工事中で機能不全な状態なので……まともにXcodeのオブジェクト階層をたどっていく気になりません。なげやりに、GUI Scripting経由でメニュー項目を呼び出したりしています。また、ビルド&実行対象は最前面のXcodeプロジェクトであって……複数のプロジェクトをXcode上でオープンしている場合に、外部エディタで編集しているScriptの所属するプロジェクトが、Xcode上でかならずしも最前面になっているわけではありませんので……そのへんは割り切って使っています。
Xcode 4でビルドを行わせる前に、AppleScriptObjC Explorer 2側でオープン中のScriptをすべてファイル保存させています。未保存のAppleScriptが存在した場合には保存をスキップします。
AppleScriptObjC Explorer 2用のScript Menuに入れて呼び出して使っています。
| スクリプト名:AppleScriptObjC Explorer2で編集中のScriptをすべて保存してXcodeでビルド実行 v2 |
tell application “AppleScriptObjC Explorer 2″ set dList to every document set sList to {} repeat with i in dList –documentのfile属性を取得(未保存だとmissing valueになっている) set tmpFile to file of i if tmpFile is not equal to missing value then tell i –保存済みのdocumentのみ保存を実行 save set the end of sList to tmpFile end tell end if end repeat end tell
–複数のプロジェクトをオープンしている場合にはアクティブ(最前面)のプロジェクトを対象に –すごい投げやりな処理…… tell application “Xcode” set curPrjDoc to active workspace document –最前面のプロジェクトが、必ずしもAppleScriptObjC Explorer 2で編集中のScriptが所属するプロジェクトとは限らない –編集中のScriptのファイルパスから上位フォルダに存在するXcode書類を探索して、プロジェクトを特定してもいいかも –ただ、Xcodeのタコさ加減にめまいがして、真剣にXcodeをAppleScriptからつっつく気になれない…… tell curPrjDoc build –ビルド end tell end tell
–GUI Scriptingから実行指定 activate application “Xcode” tell application “System Events” tell process “Xcode” click menu item “Run” of menu 1 of menu bar item “Product” of menu bar 1 end tell end tell
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode, 10.7対応, AppleScriptObjC Explorer 2 | No Comments »
Xcodeのバージョン4.2.1、およびiTunesのバージョン10.5.1が登場しています。
ともにAppleScript用語辞書の内容に変更はありません。
Posted in 10.6対応, news, Xcode, iTunes, 10.7対応 | No Comments »
XcodeのAppleScriptによる自動化は、割とニーズがあると思ってときおり調べているのですが……肝心のAppleのXcode開発チームがトンチンカンな対応をしているので、正直まだ手応えがありません。
その、悩み多きXcodeのAppleScript対応の歴史をひもとくと……
■Xcode 2.5〜3.2.3
Xcodeの最初のバージョン。Project Builder 2.4の続きのバージョン番号を振られて2.5になった。
この間、ずっと用語辞書に変更なし。用語が大量に定義されてはいるものの、ほとんどAppleScript Studioの予約語。Xcode自体の自動化はほとんどできないも同然だった。
唯一、Plugin Suiteを使ってAppleScriptによるXcodeプラグインを作成し、Xcode自身のメニュー構成をAppleScriptから変更して「使わないメニュー項目を整理するプラグイン」や「AppleScript Studio入力補助プラグイン」などが作れる状態。プロジェクト全体に対して何らかの操作を加えるという機能は提供されていなかった(自前でプロジェクト内のファイルを調べるぐらい)。
■Xcode 3.2.4
AppleScript Studioの予約語が大量に入っている状態だが、変化が生じる。AppleScriptでXcodeのプラグインを作れる「Plugin Suites」をいきなりバッサリ廃止(一番使い物になった部分を廃止してどうする?)
Appleの担当者が用語辞書に手を加えはじめる。ただし、試行錯誤が随所に見受けられる。ものすごく悩みながらやっている雰囲気。
■Xcode 4.0.1
AppleScript Studioの予約語をバッサリ削除。Xcode上のAppleScript開発環境をAppleScriptObjCに移行させ、Xcode自体にAppleScript Studioの予約語をのせておく必要性がなくなったため。
■Xcode 4.1
「To Be Removed Suites」「Tier2 Suites」など相変わらず暫定版の香りがする。
■Xcode 4.2
「To Be Removed Suites」を削除。「Tier2 Suites」を整理。
しかし、あいかわらず「ユーザーが何をするか」を考慮しないで設計しているので、Scripterから見ても「使い物にならない」雰囲気がたっぷりです。
Xcode 4.xではマイナーバージョンが上がっただけでScriptの互換性がなくなるし、XcodeのAppleScript用語は迷走に迷走を重ね、より「ダメな方向」に進む可能性が。
もう、Xcodeの担当者が○○なことは十分に分ったので、○○さ加減を全世界に宣伝しなくてけっこうです。実用性のある用語を備えるようにしてほしいです。
XcodeをASからこづき回すのは「何のため」なのかをもう一度問い直していただきたい。たとえば……
・大量のプロジェクトのビルド設定を変更して、個別にクリーニングしてビルド、生成した実行ファイルをアーカイブしてSFTPでアップロード
・FileMaker ProのDBからLocalized.stringsファイルを生成。内容を置き換える
・現在編集中のソースファイルの選択部分を取得して、何らかの処理をScriptで加えたあとに選択部分に返す
・すでに存在しているプロジェクトにCode Signingを行い、Sandbox設定を行ったのちにビルド。ビルド時にエラーが出ないかどうかコンソールに出力する
・現在オープン中のプロジェクトが、何のテンプレートを元に作成されたのかを取得(プロジェクトの種別判定)
・プロジェクトの設定へのアクセス、プロジェクト内の各ファイルへのアクセス
・編集中の(テキストベースの)書類に対する操作
……と、ざっとXcodeの自動化処理なんてだいたいこのぐらいができればよさそうなもの。それなのに、ブレークポイントをこづき回してみたり奇怪なオブジェクト階層を作ってみたりと、おおよそ生産的でない仕事を繰り広げている状況です。
Posted in アプリケーション操作(app control), 10.6対応, news, Xcode, 10.7対応 | No Comments »
Xcode 3.2.4で現在編集中のプロジェクトのビルドターゲットがテストラン時に作成したpreferenceファイル(plistファイル)を削除するAppleScriptです。
Shane Stanleyの「AppleScriptObjC Explored」を購入して熟読し、AppleScriptObjCの使い方がようやく掴めてきた今日このごろ。Xcodeも(ADC Online Developperに公開されている中で)最新のXcode 3.2.4をダウンロード。
Xcode上でAppleScriptObjCを使ってようやく作りたいものが作れるようになりかけてきたときに、やっぱり初期設定ファイル(ホーム/ライブラリ/Preferences フォルダ以下に作られるplistファイル)を削除したくなって、従来のバージョンを試してみたところ……なんと、削除されません。

いろいろ調べてみると、このわずかにバージョン番号が上がった間にXcodeのプロジェクト仕様に一部変更が(ーー; info.plistファイルのファイル名およびinfo.plist自体をビルド時にプリプロセッサで処理することがデフォルトになったらしく、ビルド前のXcodeプロジェクト内にあるinfo.plistファイルをそのまま読んできただけでは、うまく処理できません。


そこで、Xcode 3.2.4の仕様に合わせて書き換えてみました。
相変わらず、複数のビルドターゲットを持つXcodeプロジェクトには対応できていませんが、サンプルコードの中にそうのがあったので、そのうち対応するかもしれません。
| スクリプト名:現在編集中のXcodeプロジェクトのビルドターゲットが生成したpreferenceファイルを削除する v4 |
| (*
v4 : Xcode 3.2.4に対応
Xcodeプロジェクト内のinfo.plistファイルの記述内容が、プリプロセッサの処理が必要な形式で書かれるように変更されていたため、 ${PRODUCT_NAME:identifier}の値をプロジェクトのproduct nameに置換して処理するようにした。
info.plistのファイル名を、プロジェクトのactive targetの名称から取得している。 複数のactive targetを含むようなプロジェクトでは使えないはず ただし、複数のactive targetのプロジェクトがあれば、各active targetに対してループ処理すればいいだけなので、対応はそれほど難しくはない
*)
–現在編集中のXcodeプロジェクトのパス情報を取得 tell application “Xcode” try set aPrj to project of active project document on error activate display dialog “There is no Xcode Project” with icon 1 buttons {“OK”} default button 1 return end try tell aPrj set projPath to real path set pName to name of active target –active targetが複数の場合を考慮していない end tell end tell
–現在編集中のプロジェクトに含まれるInfo.plistファイルを検出 set projPath to POSIX file projPath
tell application “Finder” set parantFol to (folder of file projPath) as alias tell folder parantFol set infoP to every file whose name contains “info.plist” if infoP = {} then display dialog “現在編集中のプロジェクトにはInfo.plistが入っていません。” buttons {“OK”} default button 1 with icon 1 return end if set infoP to (first item of infoP) as alias end tell end tell
–Info.plistファイルからバンドル情報を取得する –set pListPath to (parantFol as string) & “Info.plist” tell application “System Events” set vRec to value of property list file (infoP as string) –plist fileから値を読み取る end tell set infoRes to |CFBundleIdentifier| of vRec
–plistファイルを消す set aPath to (path to preferences from user domain) as string set infoPlistPath to aPath & infoRes & “.plist”
–Xcodeプロジェクト内のinfo.plistは、まだプリプロセッサで書き換えられる前のものが入っているので、書き換えておく set infoPlistPath to repChar(infoPlistPath, “${PRODUCT_NAME:identifier}”, pName) of me
try do shell script “rm -f “ & quoted form of POSIX path of infoPlistPath tell application “Xcode” activate display dialog “以下のplistファイルを消去しました。” & return & infoPlistPath buttons {“OK”} default button 1 with icon 1 end tell on error tell application “Xcode” activate display dialog “plistファイルの消去に失敗しました” buttons {“OK”} default button 1 with icon 1 end tell end try
–文字置換ルーチン on repChar(origText, targStr, repStr) set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr} set temp to text items of origText set AppleScript’s text item delimiters to repStr set res to temp as text set AppleScript’s text item delimiters to txdl return res end repChar
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode | No Comments »
オープン中のXcodeプロジェクトの中に含まれるフレームワークのパスを取得するAppleScriptです。Xcode 3.2.2上でテストしてみました。

Xcodeプロジェクト内の「Frameworks」グループ内にある「Linked Frameworks」グループと、「Other Frameworks」グループの中に含まれるフレームワークのパス(real path)を取得します。real pathだけでなく、相対パスなどをはじめ、さまざまな情報を取得できるので、まずはpropertiesでプロパティを取得して様子を見てみるとよいのではないでしょうか?
| スクリプト名:オープン中のXcodeプロジェクトのフレームワークのパスを取得する |
–現在編集中のXcodeプロジェクトのパス情報を取得 tell application "Xcode" try set aPrj to project of active project document on error activate display dialog "There is no Xcode Project" with icon 1 buttons {"OK"} default button 1 return end try –各フレームワークの絶対パスを取得 tell aPrj set gList to name of every group –> {"Scripts", "Resources", "MainMenu.xib", "InfoPlist.strings", "Other Sources", "Frameworks", "Linked Frameworks", "Other Frameworks", "Products"}–名前をとってみただけ tell group "Frameworks" tell group "Linked Frameworks" set cList to contents set linkedFrameworkList to {} repeat with i in cList tell i set the end of linkedFrameworkList to real path end tell end repeat end tell tell group "Other Frameworks" set oList to contents set otherFrameworkList to {} repeat with i in oList tell i set the end of otherFrameworkList to real path end tell end repeat end tell end tell end tell end tell
log {"linkedFrameworkList", linkedFrameworkList} (*linkedFrameworkList, /System/Library/Frameworks/Cocoa.framework, /System/Library/Frameworks/AppleScriptKit.framework*)
log {"otherFrameworkList", otherFrameworkList} (*otherFrameworkList, /System/Library/Frameworks/Foundation.framework, /System/Library/Frameworks/AppKit.framework*)
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode | No Comments »
Xcodeで編集中のプロジェクトに含まれる各AppleScriptの行数をレポートするAppleScriptです。
まずは、Xcode 3.1.4(Mac OS X 10.5)もしくは3.2.2(Mac OS X 10.6)上でAppleScript Studio/AppleScriptObjCなどのプロジェクトをオープンしている状態で、本Scriptを実行します。
すると、プロジェクトに含まれる(正確にいえば、xcodeprojファイルと同階層にある)「.applescript」のファイルをすべて集計し、プロジェクト全体のAppleScriptの行数と、各Scriptの行数をダイアログで表示します。

なが〜いプログラムを書いてしまったときに、どのへんのプログラムをそろそろ再度分割しなければならないだろうか、といった目安にしたり、こんなにプログラムを書いてしまったのかとイヤ〜な気分になりたい時に使います。
別に、AppleScriptでなくてもObjective-CのプログラムでもC++のプログラムでも集計できますし(拡張子でファイルを指定している箇所を変更するだけ)、プロジェクトの下位フォルダの内容をすべて(entire contentsで)たどって調べてもよいでしょう。
| スクリプト名:編集中のXcodeプロジェクトに含まれる各Scriptの行数をレポート |
–現在編集中のXcodeプロジェクトのパス情報を取得 tell application “Xcode” try set aPrj to project of active project document on error activate display dialog “There is no Xcode Project” with icon 1 buttons {“OK”} default button 1 return end try tell aPrj set projName to name set projPath to real path end tell end tell
–現在編集中のプロジェクトに含まれるInfo.plistファイルを検出 set projPath to POSIX file projPath
tell application “Finder” set parantFol to (folder of file projPath) as alias tell folder parantFol set asList to (every file whose name ends with “.applescript”) as alias list end tell end tell
set resList to {} set tNum to 0 repeat with i in asList tell application “Finder” set aName to name of i end tell set aPosixPath to quoted form of POSIX path of i set aRes to do shell script (“wc -l “ & aPosixPath) set aNum to first item of words of aRes set tNum to tNum + (aNum as number) set the end of resList to ((aNum as string) & “—–” & aName) end repeat
choose from list resList with prompt (“プロジェクト「” & projName & “」(総行数=” & tNum as string) & “行)内の各Scriptの行数” with title “Script行数レポート” |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, 10.6対応, Xcode | No Comments »
Xcodeで表示中のAppleScriptのプログラム(おそらく、AppleScript Studio)から、「–」ではじまるコメント行だけを抽出して、表示するAppleScriptです。
Xcode上で編集中のAppleScript Studioのプログラムを解析してコメントだけを抜き出すAppleScript、ということになります。

▲赤い行がコメント(本Blogでもおなじみの書式)

▲本AppleScriptを実行したところ。プログラム中のコメントだけを抜き出してダイアログ表示
なが〜いプログラムを組んでしまうと、ファイル数は増えるわ、全体の構造は忘れがちだわで……たまに、全体の構造を見直してみたくなる時があります。そういう場合に使えることでしょう。
行の途中からはじまるコメントには対応していませんし、「(*」〜「*)」でかこったコメントも対応していませんが、そこは個人の趣味なので。そこまで拾って表示したい方は、ぜひ手を加えてみてください。
Xcode 3.1.4 on Mac OS X 10.5.8と、Xcode 3.2.2 on Mac OS X 10.6.3上で動作確認してあります。
ちなみに、Xcode 3.1.4やXcode 3.2.2上ではAppleScript StudioのソースコードをUTF-8で書けるようになっているので、UTF-8で書くようにしています。そのため、AppleScript Studioのソースコードファイルを読むときにUTF8を指定して読み込んでいます。
| スクリプト名:Xcodeで表示中のASのファイルからコメントだけ抽出 |
tell application “Xcode” set wCount to count every window if wCount = 0 then display dialog “Xcodeで何らかのプロジェクトをオープンした状態で実行してください” buttons {“OK”} default button 1 with icon 1 return end if try save on error return end try tell window 1 set aPath to associated file name end tell end tell
–Xcode上で表示中の内容がAppleScriptでなければリターン if aPath does not end with “.applescript” then return end if
–ファイルシステム上から表示中のファイルを直接読み込み set aText to read POSIX file aPath as «class utf8» set aList to paragraphs of aText
–ハンドラリストを作成 set hList to {} set hCount to 1 repeat with i in aList set j to contents of i ignoring white space if j begins with “–” then set a to retUTF8(j) of me set the end of hList to a end if end ignoring set hCount to hCount + 1 end repeat
choose from list hList with prompt “Xcodeで表示中のAppleScriptのコメント” with title “コメント抽出結果:”
on retUTF8(theText) set the clipboard to (theText as international text) –International はunicodeの同義語 set ss to (the clipboard as record) return «class utf8» of ss end retUTF8 |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, 10.6対応, Xcode | No Comments »
Xcodeで表示中のAppleScript Studioのプログラムの、各ハンドラ行数をカウントして、長い順にソートして、画面表示するAppleScriptです。Xcode 3.2.2+Mac OS X 10.6.3で動作確認を行っていますが、Xcode 3.1.4+10.5.8でも動作するはずです。
つまりこれは、「Xcode上のAppleScriptのプログラム」を解析するAppleScriptのプログラムです。
AppleScript Studioのプログラムは、1ファイルあたりの編集・実行可能な上限が存在するため、だいたい1000行をメドに複数のファイルに分割する必要があります。Xcode 3.1.4+Mac OS X 10.5.8の環境では、2500行ぐらいに達するとビルドできなくなったり、意味不明のエラーが発生するようになってしまいます。
そんなわけで、行数が増えてくるとハンドラ単位で別ファイルに分割して、分割ローディングする必要が出てくるわけですが、その分割候補となるのが行数の長いハンドラ。
各ハンドラ/イベントハンドラの行数を集計し、長い順にソートし、ダイアログ表示します。AppleScript Studioのプログラムが対象であり、AppleScript ObjCのプログラムは対象にしていません(短いのはテストしているんですが、ASOCではそんなに長いのを組んでいないもので)。
XcodeのエディタでAppleScriptエディタなみにScriptの書式情報にアクセスできれば、かなり突っ込んだ処理も可能なのですが……指定のハンドラと、それに関連するサブルーチンをまとめて別のScriptファイルに移動させるといったことも処理できそうではあるのですが、現状のXcodeの用語辞書では非常に困難です。
| スクリプト名:Xcodeで表示中のScriptの各ハンドラ行数をカウント |
tell application “Xcode” set wCount to count every window if wCount = 0 then display dialog “Xcodeで何らかのプロジェクトをオープンした状態で実行してください” buttons {“OK”} default button 1 with icon 1 return end if try save on error return end try tell window 1 set aPath to associated file name end tell end tell
–Xcode上で表示中の内容がAppleScriptでなければリターン if aPath does not end with “.applescript” then return end if
–ファイルシステム上から表示中のファイルを直接読み込み set aText to read POSIX file aPath set aList to paragraphs of aText
–ハンドラリストを作成 set hList to {} set hCount to 1 repeat with i in aList set j to contents of i ignoring white space if ((j begins with “on”) and (j does not contain “on error”)) or ((j begins with “to”) and (j does not contain “on error”)) then if j contains “(” and j contains “)” then –ハンドラ set j1 to offset of “on “ in j set j2 to offset of “(” in j set aHandle to text (j1 + 3) thru (j2 - 1) of j else if j contains “theObject” then –イベントハンドラ set j1 to offset of “on “ in j set j2 to offset of ” theObject” in j set aHandle to text (j1 + 3) thru (j2 - 1) of j end if set the end of hList to {aHandle, hCount} end if end ignoring set hCount to hCount + 1 end repeat
–各ハンドラ末尾をサーチして{ハンドラ名、開始行、終了行、行数}をリスト化 set hCount to 1 repeat with i from 1 to (length of hList) set {aHandler, sLine} to contents of item i of hList repeat with h from (sLine + 1) to (length of aList) set aCon to contents of item h of aList ignoring white space if aCon begins with “end “ & aHandler then set the end of item i of hList to h set the end of item i of hList to (h - sLine) exit repeat end if end ignoring end repeat end repeat
–降順ソート set h2List to shellSortListDecending(hList, 4) of me
–表示用のリストを作成 set h3List to {} repeat with i in h2List set {hName, sNum, eNum, tNum} to i set aCon to (tNum as string) & “—–” & hName set the end of h3List to aCon end repeat
choose from list h3List with prompt “Xcodeで表示中のAppleScriptの各ハンドラ/イベントハンドラの行数” with title “ハンドラ集計結果:”
–シェルソートで入れ子のリストを降順ソート on shellSortListDecending(a, keyItem) set n to length of a set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of a set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of a) < (item keyItem of v)) set (item (j + 1) of a) to (item (j - h + 1) of a) set j to j - h end repeat set item (j + 1) of a to v end repeat end if end repeat return a end shellSortListDecending
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, 10.6対応, Xcode | No Comments »
Xcode 3.1.4上で編集中のプロジェクトで、テスト実行を行った際にユーザーディレクトリ下に作成したplistファイルを削除するAppleScriptです。
以前のバージョンでは、複数のXcodeプロジェクトを同時にオープンしていた際に、最初にオープンしたプロジェクトを対象としてplistの削除を行うという不具合があったため、本バージョンではアクティブな(編集中の、最前面にある)プロジェクトを対象としてplist削除を行うように書き換えてみました。
また、以前のバージョンではどのplistファイルを消したのか、いっさい告知を行っていなかったので……作業終了時にパス名を表示するように機能を追加しました。地味に便利な機能です(display dialogに変数を追加しただけですが)。
Xcodeのプロジェクトを複数ひらいて、過去のプロジェクトを参照したりサンプルコードを参照するという作業は、割とよくあることなので……複数プロジェクトオープン時に最前面のプロジェクトを特定する方法が存在していたのはラッキーでした。
Xcode 3.1.4がターゲットであり、目下最新版のXcode 3.2.2では動作検証を行っていませんが……多分、動くと思います。
このAppleScriptを書いてからというもの、Xcode上でAppleScript Studioのプログラム開発を行う際には必須ともいえる存在となりました。意外と、「中途半端な作りのplistファイル」が残ったままになっているために起きるトラブル(というより、エラーが出なくてはならないのにplistファイルが残っているために見過ごされるエラー)は多く、自分も「okaeri」のリリース後に他人の環境で起動できないトラブル、というのに巻き込まれて……しばらくダメージから回復できませんでした(問題があったら知らせてほしいな〜)。
本Scriptを使用することで、実行環境におけるplistを削除できるため、plist回りのトラブルを回避できます。Xcodeの標準機能としてこれぐらい入れておいてほしいぐらいです(cleanコマンドにこの機能がないのはおかしいよ)。本当にないと困ります。Xcode+AppleScriptでアプリケーション開発を行う際には、毎日使っています。Objective-CやC++などの言語で開発していても、たぶん手放せないものになることでしょう。
Xcodeの自動化は、生産性をひじょーーに左右するものなので、Appleにはもっと真剣に取り組んでもらいたいものです。XcodeのAppleScript用語辞書が中途半端なので、もっと充実させるべきです。
| スクリプト名:現在編集中のXcodeプロジェクトのビルドターゲットが生成したpreferenceファイルを削除する v3 |
–現在編集中のXcodeプロジェクトのパス情報を取得 tell application “Xcode” try set aPrj to project of active project document on error activate display dialog “There is no Xcode Project” with icon 1 buttons {“OK”} default button 1 return end try tell aPrj set projPath to real path end tell end tell
–現在編集中のプロジェクトに含まれるInfo.plistファイルを検出 set projPath to POSIX file projPath
tell application “Finder” set parantFol to (folder of file projPath) as alias tell folder parantFol set infoP to exists of file “info.plist” if infoP = false then display dialog “現在編集中のプロジェクトにはInfo.plistが入っていません。” buttons {“OK”} default button 1 with icon 1 return end if end tell end tell
–Info.plistファイルからバンドル情報を取得する set pListPath to (parantFol as string) & “Info.plist” tell application “System Events” set vRec to value of property list file (pListPath as string) –plist fileから値を読み取る end tell set infoRes to |CFBundleIdentifier| of vRec
–plistファイルを消す set aPath to (path to preferences from user domain) as string set infoPlistPath to aPath & infoRes & “.plist”
try do shell script “rm -f “ & quoted form of POSIX path of infoPlistPath tell application “Xcode” activate display dialog “以下のplistファイルを消去しました。” & return & infoPlistPath buttons {“OK”} default button 1 with icon 1 end tell on error tell application “Xcode” activate display dialog “plistファイルの消去に失敗しました” buttons {“OK”} default button 1 with icon 1 end tell end try
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, 10.6対応, Xcode | No Comments »
Xcode上で編集中のプロジェクトのビルドターゲットがテストラン時に生成したplistファイルを削除するAppleScriptです。Xcode 3.1.4をターゲットに作成したものですが、Xcode 3.2.xでも多分動くことでしょう。
AppleScriptによるXcodeの自動化というのは、本当にやりたい処理があってもXcodeのAppleScript対応機能が不十分で実装できないことが多くて実現できないケースが多いのですが……このケースではキレイにできました。Xcodeの単純なプロジェクト(ビルドターゲットが1つだとか、一般的なデスクトップアプリケーションのプロジェクトだとか)向けに作ったので、プラグインとかkextとかのプロジェクトまでは考慮していません。
AppleScriptからXcodeに問い合わせてプロジェクトのタイプなども取得できるとよいのですが……そういう「実践的な機能」というのが載ってこないのがXcodeのAppleScript辞書の不思議なところです。絶対に、AppleScriptの記述経験がほとんどないエンジニアが実装を行わされているに違いない、と思わせるものがあります。
Xcode(AppleScript StudioとかAppleScriptObjC)でプログラムを組んでいて、テストラン時に生成されたplistファイルが邪魔になってきちんと動作検証できないケースがあります。本来はうまく動いてはいけないものが、過去にテストランしたときのplistファイルが残ってしまっていたために「動いてしまった」とか。
そのため、plistファイルを手でいちいち消していました。Xcodeのクリーンコマンドは、ビルドフォルダ内のファイルは消去してくれますが、plistファイルは消してくれません。割とよく使う処理だったので、AppleScriptで自動化してみました。なにげに便利です。
| スクリプト名:現在編集中のXcodeプロジェクトのビルドターゲットが生成したpreferenceファイルを削除する v2 |
–現在編集中のXcodeプロジェクトのパス情報を取得 tell application “Xcode” tell project 1 set projPath to real path end tell end tell
–現在編集中のプロジェクトに含まれるInfo.plistファイルを検出 set projPath to POSIX file projPath
tell application “Finder” set parantFol to (folder of file projPath) as alias tell folder parantFol set infoP to exists of file “info.plist” if infoP = false then display dialog “現在編集中のプロジェクトにはInfo.plistが入っていません。” buttons {“OK”} default button 1 with icon 1 return end if end tell end tell
–Info.plistファイルからバンドル情報を取得する set pListPath to (parantFol as string) & “Info.plist” tell application “System Events” set vRec to value of property list file (pListPath as string) –plist fileから値を読み取る end tell set infoRes to |CFBundleIdentifier| of vRec
–plistファイルを消す set aPath to (path to preferences from user domain) as string set infoPlistPath to aPath & infoRes & “.plist”
try do shell script “rm -f “ & quoted form of POSIX path of infoPlistPath tell application “Xcode” activate display dialog “plistファイルを消去しました” buttons {“OK”} default button 1 with icon 1 end tell on error tell application “Xcode” activate display dialog “plistファイルの消去に失敗しました” buttons {“OK”} default button 1 with icon 1 end tell end try
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, 10.6対応, Xcode, System Events | No Comments »
Xcode 3.2.1で、プロジェクトの論理的な内部構造にアクセスするためのオブジェクトが、どうやら「project」オブジェクトのようです。このprojectオブジェクトの下にブラ下がっているオブジェクトに対して階層的にアクセスを行うことで、AppleScriptでどのような処理を行うことができるかが明らかになります。
特徴的なのは、ビルド結果の実行ファイル(executables)にアクセスできるのと、プロジェクト内のファイルへのアクセスが、一般的なファイルパスで行うのではなく「file reference id ”4F422FE710A3F035008C18C1”」といった形式で行う必要があるということです。他のさまざまなbuild targetなどもこのようなid形式で管理されているため、アプリケーション側の流儀に合わせてアクセスする必要があります。
★何らかのXcodeプロジェクトをオープンした状態で実行してください
| スクリプト名:Xcode 3.2.1でプロジェクトの属性情報を取得する |
–Xcode 3.2.1でプロジェクトの属性情報を取得する tell application “Xcode” tell project 1 properties –> {project roots:{”"}, intermediates directory:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/build/ASOC Task List.build/Debug”, root group:group id “29B97314FDCFA39411CA2CEA” of project “ASOC Task List” of application “Xcode”, active architecture:”x86_64″, active target:target id “8D1107260486CEB800E47090″ of project “ASOC Task List” of application “Xcode”, organization name:missing value, active executable:executable id “4FE9A6DD109F2002003C067D” of project “ASOC Task List” of application “Xcode”, real path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, full path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, read only:false, name:”ASOC Task List”, default build configuration type:build configuration type id “C01FCF5008A954540054247B” of project “ASOC Task List” of application “Xcode”, active build style:missing value, id:”29B97313FDCFA39411CA2CEA”, active build configuration type:build configuration type id “C01FCF4F08A954540054247B” of project “ASOC Task List” of application “Xcode”, class:project, project directory:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList”, user file reference:file reference id “4F422FE710A3F035008C18C1″ of project “ASOC Task List” of application “Xcode”, active SDK:missing value, product directory:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/build/Debug”, currently building:false, project file reference:file reference id “4F422FE810A3F035008C18C1″ of project “ASOC Task List” of application “Xcode”} end tell end tell |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode | No Comments »
Xcode 3.2.1で、最前面のウィンドウ(window 1)でオープンしているファイルを取得するAppleScriptです。
Xcodeにかぎらず、アプリケーションがオープンしている書類にアクセスする手段には大きくわけて2つがあり、1つがドキュメント(実在するファイルであることが多い)、もう1つがウィンドウです。実データにアクセスする場合にはドキュメントからたどって行く場合が多く、documentオブジェクト経由のアクセスがほとんどです。
ただし、現在表示されているドキュメント(最前面に表示されているドキュメント)が何なのかを調べたり、ドキュメントの表示方法(複数の表示モードが存在するような場合)を調べるような場合にはWindow経由でアクセスすることになります。
まさに、Xcode 3.2.1で最前面のウィンドウで何を表示しているのかを取得するようなケースでwindow経由のアクセスを行うことになります。

Xcodeでは、1つのウィンドウを分割して複数のソースコードを表示できるようになっていますが、Windowオブジェクトが返す書類はつねに1つで、1ウィンドウ内に複数のファイルを表示している場合には、フォーカスが当たっている方(カーソルがアクティブになっている方)を返すようです。1ファイル=1ウィンドウの設定(ウィンドウがたくさんひらく)の場合にも同じです。
windowオブジェクトで注目すべきは、「associated file name」です。Windowでオープン中のドキュメントのフルパスを(aliasではなくPOSIX pathで)取得できます。フルパスを渡すための属性値ということで、正しくは「associated file path」という名前が正解だと思うのですが、なんでこのような名前にしてしまったのか、たいへん不思議です。
★何らかのXcodeプロジェクトをオープンした状態で実行してください
| スクリプト名:Xcode 3.2.1で最前面のWindowでオープンしているファイルを取得 |
–Xcode 3.2.1で最前面のWindowでオープンしているファイルを取得 tell application “Xcode” tell window 1 properties –> {associated file name:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/TaskListAppDelegate.applescript”, bounds:{34, 129, 1307, 1028}, main:false, miniaturized:false, key:false, script:missing value, level:0, sheet:false, modal:false, document edited:false, position:{34, 129}, closeable:true, released when closed:false, name:”TaskListAppDelegate.applescript ― ASOC Task List”, content view:content view of window id 1 of application “Xcode”, minimized title:”TaskListAppDelegate.applescript ― ASOC Task List”, background color:{61166, 61166, 61166}, has shadow:true, has resize indicator:true, miniaturizable:true, maximum size:{5000, 5053}, first responder:text view id 11 of content view of box id 10 of view id 9 of split view id 8 of view id 7 of view id 6 of tab view id 5 of view id 4 of view id 3 of view id 2 of window id 1 of application “Xcode”, resizable:true, current field editor:missing value, visible:true, opaque:true, minimum size:{200, 231}, id:1, alpha value:1.0, class:window, needs display:false, zoomed:false, size:{1273, 899}, zoomable:true, titled:true, minimized image:missing value, floating:false, document:missing value, excluded from windows menu:false, auto display:true, index:1, toolbar:toolbar of window id 1 of application “Xcode”, title:”TaskListAppDelegate.applescript ― ASOC Task List”, menu:main menu of application “Xcode”, can hide:true, hides when deactivated:false} –ウィンドウでひらいているファイルのフルパス set aPath to associated file name –> “/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/TaskListAppDelegate.applescript” –Xcode上では複数のドキュメントをウィンドウ分割で表示することも可能だが、あくまでも「フォーカスが当たっている」方のファイルのパスが返ってくる end tell end tell |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode | No Comments »
Xcode 3.2.1にとって、「document」というのはプロジェクトの書類(拡張子が「.xcodeproj」の、青いアイコンの書類)です。そのプロジェクト書類にアクセスするためのオブジェクトが「project document」で、「document」と等価な扱い(同じ結果が返ってくる)のようですが、さまざまな属性を取得して調べてみるとproject documentが使われているようなので、こちらからアクセスしてみました。
期待したような属性値に加えて、SCM(ソースコード管理)関連の属性も入っていたりするので、このあたりの機能をAppleScriptから呼び出せそうな「予感」を感じるものです。
★何らかのXcodeプロジェクトをオープンした状態で実行してください
| スクリプト名:Xcode 3.2.1上でプロジェクト書類の情報を取得する |
–Xcode 3.2.1上でプロジェクト書類の情報を取得する tell application “Xcode” tell project document 1 properties –属性情報の一括取得 (* –> {path:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, project:project “ASOC Task List” of application “Xcode”, class:project document, scm transcript:”< ?xml version=\"1.0\" encoding=\"UTF-8\"?> “, file name:”/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj”, id:7, file kind:”Xcode Project File”, script:missing value, modified:false, file type:”Xcode Project File”, name:”ASOC Task List.xcodeproj”} *) set aPath to path –Xcodeプロジェクトのパス –> “/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj” set aSCMtrans to scm transcript (* –> –> “< ?xml version=\"1.0\" encoding=\"UTF-8\"?> “ *) set aFileName to file name –> “/Users/maro/Documents/Develop/AppleScriptObjC/ASOCTaskList/ASOC Task List.xcodeproj” set anID to id –> 7 set fKind to file kind –> “Xcode Project File” set modifyFlag to modified –> false set fType to file type –> “Xcode Project File” set aName to name –> “ASOC Task List.xcodeproj” end tell end tell |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode | No Comments »
Xcode 3.2.1でアプリケーションのプロパティを取得してみました。selectionがこの階層のオブジェクトに属しているアプリケーションもあったりするため、その確認です。
結論をいえば、この階層のオブジェクトからはとくに有用なプロパティは存在していませんでした。versionを取得してみるとか、frontmost(最前面にいるかどうか)を取得するか、active project documentで現在編集中のプロジェクト書類を取得できるとか(これは重要)いったところが見どころで、それ以外は無視してよい属性ばかりです。
★何らかのXcodeプロジェクトをオープンした状態で実行してください
| スクリプト名:Xcode 3.2.1でアプリケーションの情報を取得する |
tell application “Xcode” properties –> {frontmost:false, event:event 1 of application “Xcode”, name:”Xcode”, key window:missing value, windows menu:sub menu of menu item id 2 of main menu of application “Xcode”, user defaults:user defaults of application “Xcode”, icon image:image id 3 of application “Xcode”, open panel:open panel of application “Xcode”, script:missing value, main bundle:bundle id 4 of application “Xcode”, version:”3.2.1″, main window:missing value, menu:main menu of application “Xcode”, selection:insertion point 43 of text of text document “TaskListAppDelegate.applescript” of application “Xcode”, class:application, active project document:project document “ASOC Task List.xcodeproj” of application “Xcode”, main menu:main menu of application “Xcode”, save panel:save panel of application “Xcode”, active:false, font panel:font panel of application “Xcode”, hidden:false, color panel:color panel of application “Xcode”, id:1, coordinate system:classic coordinate system, drag info:missing value, services menu:sub menu of menu item id 5 of sub menu of menu item id 6 of main menu of application “Xcode”} end tell |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.6対応, Xcode | No Comments »
AppleScript Studioの用語辞書を抱える必要がなくなり、大幅に身軽になったXcodeのAppleScript用語辞書ですが、バージョン3.2のレベルでは実用的な(Xcodeの自動化のための)AppleScriptを書こうとしても、いまひとつ必要な情報が取り出せなかったり、必要な操作ができませんでした。
第一線のScripter連中にとってはまだまだ「及第点」に到達していないぐらいの出来でした。
Xcode上の作業自動化については、Appleがほとんど有効な手を打ってこなかったために、Apple社員がAppleScript Users ML上で質問を投げては、みんなに無視されて逆ギレするといった……一種の「ほほ笑ましい光景」が定期的に見られていたものです。
単なるバグフィックス版(Chris Espinosa・談)と見られていたXcode 3.2.1のAppleScript用語辞書を書き出して、差分をFileMergeでチェックしてみたところ、なんと172箇所も変更が加わっており……Xcode 3.2とXcode 3.2.1はAppleScript辞書だけ見ると「別物」と言っても過言ではないほど。正直、チェックして腰を抜かしました。
Xcode上で日常的に行う操作が自動化できるのか? Xcodeのコードエディタ上で生産性を向上させるようなソリューションを実現できるのか? Xcodeプロジェクト上のさまざまな属性情報や各種ドキュメント(ソースコードとか、ローカライズ用のファイルとか、Info.plistとかxibファイルとか)にアクセスできるかどうか、ひととおり調べてみる価値はありそうです。
用語辞書だけ増やしてみたものの、バグがあるとか、必要なオブジェクトが用意されていないという話はザラなので、慎重に検証を行ってみたいところです。
Posted in 10.6対応, news, Xcode | No Comments »
Xcode 3.1.3で、最前面のXcodeプロジェクトをクリーニングしてビルドし、作成したバイナリを指定ファイル名にZip圧縮します。
このScriptでZip圧縮したあとにメールに添付して送信するなり、FTPサーバーにアップロードするなり、いろいろやってみてもよいでしょう。
ただ、ビルドする対象のプロジェクトは、アプリケーションを生成するものだけではないため、そのあたりプロジェクトの種類(プラグイン、Automator Action、ドライバなど)を取得できるようにXcode側がAppleScriptに情報を渡してくれるようになっているとよいのですが、現状ではそうした配慮はありません。
| スクリプト名:XcodeでクリーニングしてビルドしてZip圧縮 |
tell application "Xcode" tell project 1 set bList to name of every build configuration set rBCon to first item of (every build configuration whose name is "Release") set cRes to clean with removing precompiled headers –> "クリーニングに成功しました" set bRes to build using rBCon –> "ビルドは問題なく完了しました (1 個の警告)" set binPath to product directory end tell end tell
set binPathAlias to POSIX file binPath
tell application "Finder" tell folder binPathAlias set appFile to (every file whose name ends with ".app") as alias list end tell end tell
set anApp to contents of first item of appFile set zipAlias to compressFileByZip(anApp, "appArch.zip") of me –> alias "Cherry:Users:maro:Documents:ぴよまるソフトウェア:高速富士山miniプロジェクト:hsmtfj_mini:v3:build:Release:hsmtfj mini.app.zip"
–ファイルをZipで圧縮して指定名称にリネーム on compressFileByZip(aFile, newName) set apPath to POSIX path of aFile set folF to false if apPath ends with "/" then set apPath to text 1 thru -2 of apPath set folF to true end if set source to quoted form of apPath – a folder set dest to quoted form of (apPath & ".zip") do shell script "ditto -ck " & source & " " & dest set apPathStr to aFile as string if folF = true then set apPathStr to text 1 thru -2 of apPathStr end if set apPathZip to apPathStr & ".zip" as alias tell application "Finder" set name of apPathZip to newName end tell return apPathZip end compressFileByZip
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »
Xcode 3.1.2で、表示中のテキスト系ファイルの指定行にカーソルを移動して表示するAppleScriptです。

▲Xcode 3.1.2でAppleScript Studioのプロジェクトをオープンしている状態。Xcode 3.1以降で採用された「ネスティング部分の折りたたみ機能」が特徴

▲本AppleScriptをスクリプトエディタやスクリプトメニューから実行すると、指定行(100行)が表示状態になる
USのAppleScript Users MLにAppleの技術者が投稿したScriptを元にしていますが、クセが強かったのでクセをなくして読みやすく書き直したものです。
実際に、指定行を固定で指定することなどはほとんどなく、Xcode上のプログラムソースコードの内容を外部からアクセスして解析し、必要な部分の行数を動的に計算して求め、その結果の行をフォーカス表示するためにこのようなAppleScriptが必要になるものと思われます。おそらく、XcodeのプラグインをAppleScriptで開発しているユーザーがMLにその方法を質問したものでしょう。
余談になりますが……AppleScriptを読みやすく書くためには、いろいろと国際的な「暗黙のルール」が存在します。
具体的にいえば、極力「it」や「the」を使用しないとか、複数行間で「the result」による値の間接受け渡しを行わず明示的に実行結果を変数に代入するとか、フィルタ参照時に「that」ではなく「whose」を使うなどといったものです。
ほかにも、変数名やサブルーチン名称の大文字小文字のかき分けにも国際的な暗黙のルールが存在し、それに則ることで海外のScripterとの間でスムースな意思疎通が行えるようになります。
| スクリプト名:Xcodeで表示中のファイルの指定行数を表示状態に |
tell application “Xcode“ tell front text document set selection to paragraph 100 – 100行目が選択状態になる end tell end tell |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »
Xcode 3.1.2で、ビルドターゲット「Deployment」でクリーニングを行い、ビルドを実行。ビルド実行後に実行バイナリを起動します。
(more…)
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »
Xcode 3.1.2で、ビルドターゲット「deployment」に対するクリーニングを行います。
(more…)
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »
Xcode 3.1.2で、オープン中のプロジェクトの各種ビルド設定の詳細情報を取得します。
(more…)
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »
Xcode 3.1.2で、オープン中のプロジェクトのビルド設定の名称一覧を取得します。
(more…)
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »
ながらく、XcodeはApple純正の開発環境でありながら、AppleScriptからまともにコントロールできないアプリケーションでした。機能を呼び出せない、状況も把握できない……本来、もっとも自動処理の恩恵を受けるべき道具にまともなAppleScript対応機能が備わっていなかったのは「情けないこと」と言って差し支えないでしょう。
しかし、状況は変わりつつあります。AppleScript Studioのエディタで日本語をまともに表示できないXcode 3.1のリリースから1年。ようやく登場したXcode 3.1.2で、多くの(すべて、ではない)バグが改修されました。
Xcode自体も、3.1でその多くの機能をAppleScriptから呼び出すことができるようになり、シェルスクリプトではなくAppleScriptで各種作業の自動化が可能になりました。
本スクリプトでは、オープン中のプロジェクトの数をかぞえます。
(more…)
Posted in アプリケーション操作(app control), 10.5対応, Xcode | No Comments »