Archive for 7月, 2014

2014/07/29 変数に入っているデータの「型」を求める

変数の中に入っているデータの「型」を求めるAppleScriptです。

  class of 変数

で求められます。

スクリプト名:変数に入っているデータの「型」を求める
set a to 1
class of a
–> integer

set b to 1.0
class of b
–> real

set c to "1"
class of c
–> text

set d to selection of application "Finder"
class of d
–> list

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/29 dateオブジェクトの加減算

dateオブジェクトの加減算の記述例です。

たとえば、現在時刻(current date)の1時間後を求めるのに……

スクリプト名:現在の1時間後を求める(ダメな例)
set a to current date

set tmpH to hours of a
set tmpH to tmpH + 1
set hours of a to tmpH

a
–> date "2014年7月29日火曜日 10:07:46"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

と書いている例に見当たりましたが……この調子で3時間20分3秒後を計算しようとすると……

スクリプト名:現在の3時間20分3秒後を求める(ダメな例)
set a to current date

set tmpH to hours of a
set tmpH to tmpH + 3
set hours of a to tmpH

set tmpM to minutes of a
set tmpM to tmpM + 20
set minutes of a to tmpM

set a to a + 3

a
–> date "2014年7月29日火曜日 22:54:10"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

のようになるので、たいへんです。

dateオブジェクトに対しての加減算は、秒単位で数値を足したり引いたりすることで計算できます。

そのさいに、分(minutes=60)、時(hours=3600)、日(days=86400)、週(weeks=604800)などの定数があらかじめ定義されているため、これらを用いることになります。

スクリプト名:現在の1時間後を求める
set a to current date

set a to a + (1 * hours)

–> date "2014年7月29日火曜日 10:07:46"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:現在の1時間前を求める
set a to current date

set a to a - (1 * hours)

–> date "2014年7月29日火曜日 10:07:46"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:現在の1日後を求める
set a to current date

set a to a + (1 * days)
–> date "2014年7月30日水曜日 11:18:23"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:現在の1日前を求める
set a to current date

set a to a - (1 * days)
–> date "2014年7月28日月曜日 19:28:52"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:現在の3時間20分3秒後を求める
set a to current date

set a to a + (3 * hours) + (20 * minutes) + (3)
–> date "2014年7月29日火曜日 12:29:41"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:現在の3時間20分3秒前を求める
set a to current date

set a to a - ((3 * hours) + (20 * minutes) + (3))
–> date "2014年7月29日火曜日 12:29:41"

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/23 Script Editorで最前面のアプリの用語辞書を表示する v3

AppleScriptエディタ/Script Editorで、最前面のアプリの用語辞書を表示するAppleScriptです。

バージョンアップして、最前面のアプリがAppleScript等のOSA(Open Scripting Architecture)言語によるScriptingに対応しているかどうかを判定したのちに、辞書のオープンを行います。

Script Menuに入れて、メニューから呼び出すことを前提としています。

前バージョンでは、とくに対象アプリケーションのScripting対応については調べていなかったため、非対応アプリを指定すると、Script Editorで対象アプリをバイナリモードでオープンしてしまうなどの問題があり、それに対処したものです。

本AppleScriptは、各アプリケーションのバンドル中にあるInfo.plistを走査してOSA対応の判定を行っていますが、これは「NSAppleScriptEnabled」のエントリがInfo.plist上に存在した場合、慣習的に「true」しか指定されていない(そもそも非対応である場合にはNSAppleScriptEnabledのエントリそのものを作らない)ことから、「NSAppleScriptEnabled」が入っていれば対応……という「手抜き判定」をやっています。

真剣に作るのであれば、NSAppleScriptEnabledのエントリを取得して属性値がどうなっているか判定すべきです。

スクリプト名:Script Editorで最前面のアプリの用語辞書を表示する v3
–最前面のプロセスのファイルシステム上の位置を取得してaliasに変換する
tell application “System Events”
  set frontProc to every process whose frontmost is true and visible is true
  
set aProc to contents of first item of frontProc
  
set aFile to file of aProc
  
set aBundleID to bundle identifier of aProc
end tell

set aFile to aFile as alias

–バンドルパッケージ中のInfo.plistファイルを走査してAppleScript対応かどうかを調べる
set aFilePosix to quoted form of POSIX path of aFile
set infoPath to aFilePosix & “Contents/Info.plist”
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)

–スクリプト用語辞書をScript Editorでオープンする手順
if aRec = true then
  –OS X 10.10でScript Editor側からアプリをオープンしてもダメだったので、Finder側からScript Editorで指定アプリをオープンすることに
  
tell application “Finder”
    set apFile to (application file id “com.apple.scripteditor2″) as alias
    
open aFile using application file apFile
  end tell
else
  tell application id aBundleID
    display dialog “本アプリケーションは、各種OSA言語によるコントロールに対応していません。” buttons {“OK”} default button 1 with icon 2 with title “Scripting非対応”
  end tell
end if

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aPosix, findStr)
  
  
try
    set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  on error
    return 0 –エラー(指定のパスにファイルが存在しない)
  end try
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/22 AS対応、非対応のアプリ数をカウントする v2

Macのローカルに存在するアプリケーションをすべてリストアップし、AppleScript対応のもの、AppleScript非対応のもの、Info.plistが所定の位置にないものをカウントして返すAppleScriptです。

Finder経由でentire contentsを取得するものを試していたのですが……結果が返ってこない。

以前はもうちょっとentire contentsは「使える」気がしたのですが、実際に試した10.9上ではおかしな動作になっていました(ディスクのチェックが必要かも)。

そこで、mdfind経由でアプリケーションファイルを/Applications以下から取得するようにしてみたところ……数秒で結果が返ってきました。結局、mdfind(spotlight)系の(いつもの)ルーチンを使用することに。

「Info.plistが見つからない」とレポートされたアプリケーションの一覧を調べてみると、以前にWeb CGIとして作成した拡張子「.acgi」のAppleScriptのアプリとか、むか〜しのバンドル形式ではないフォーマットの(10.7以降では実行することができない)アプリケーションとか、あろうことかClassic形式のアプリケーションなどでした。

結局これを、アプリケーションのstringsファイルのローカライズ情報の取り出し(&データベースへの格納)のために使いたかった、という話で……けっこういろいろ寄り道してしまいました。

なお、プログラムリストの途中にシングルクォートが入っていたのでうまくWordPressに投稿できず(全角クォートとかに置き換える必要アリ?)、末尾の既出のサブルーチンはリストからは割愛してあります。

AppleScriptのHTML書き出し用AppleScriptを修正し、バックスラッシュとシングルクォートを全角文字に置き換えて出力するようにしました(記事が全部バックスラッシュになる怪奇現象に遭遇していましたが、これで解決)。

いつもどおり、プログラムリスト末尾のリンクをクリックすると、プログラム全体がAppleScriptエディタ/スクリプトエディタに転送されるようになっています。

スクリプト名:AS対応、非対応のアプリ数をカウントする v2
script spd
  property origList : {} –/Applications フォルダ以下のアプリケーションファイル一覧
  
  
property asEnable : {} –AS対応のアプリ一覧
  
property asDisable : {} –AS非対応のアプリ一覧
  
property infoNotPresent : {} –Info.plistが所定の場所に指定のファイル名で存在しないもの一覧
end script

set origList of spd to {}

set asEnable of spd to {}
set asDisable of spd to {}
set infoNotPresent of spd to {}

set apPath1 to (path to applications folder) as string

–mdfindで指定フォルダ以下にあるすべてのアプリケーションファイルを取得
set (origList of spd) to getFileListWithSpotLight(“kMDItemKind”, “アプリケーション”, apPath1) of me

repeat with i in (origList of spd)
  
  
set aFilePosix to quoted form of POSIX path of i
  
set infoPath to aFilePosix & “Contents/Info.plist”
  
  
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)
  
  
if aRec = true then
    set the end of (asEnable of spd) to i
  else if aRec = false then
    set the end of (asDisable of spd) to i
  else
    set the end of (infoNotPresent of spd) to i
  end if
end repeat

return {length of (asEnable of spd), length of (asDisable of spd), length of (infoNotPresent of spd)}
–> {294, 580, 36}

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aPosix, findStr)
  
  
try
    set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  on error
    return 0 –エラー(指定のパスにファイルが存在しない)
  end try
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

–指定階層下で、指定メタデータが指定パラメータであるファイルを取得(alias list)
on getFileListWithSpotLight(aMetaDataItem, aParam, startDir)
  
  
set sDirText to quoted form of POSIX path of startDir
  
set shellText to “mdfind ’” & aMetaDataItem & ” == \”" & aParam & “\”’ -onlyin “ & sDirText
  
try
    set aRes to do shell script shellText
  on error
    return {}
  end try
  
set pList to paragraphs of aRes
  
set aList to {}
  
repeat with i in pList
    set aPath to POSIX file i
    
set aPath to aPath as alias
    
set the end of aList to aPath
  end repeat
  
return aList
end getFileListWithSpotLight

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/22 AS対応、非対応のアプリ数をカウントする

Macのローカルに存在するアプリケーションをすべてリストアップし、AppleScript対応のもの、AppleScript非対応のもの、Info.plistが所定の位置にないものをカウントして返すAppleScriptです。

下調べのために作ってみました。

すぐに「entire contentsで指定フォルダ以下のファイルをすべて取得してアプリのみ抽出するバージョン」に作り替えていますが……まだ、処理が返ってきません、、、

スクリプト名:AS対応、非対応のアプリ数をカウントする
script spd
  
  
property aList1 : {} –/Applications フォルダ以下のアプリケーションファイル一覧
  
property aList2 : {} –/Applications/Utilities フォルダ以下のアプリケーションファイル一覧
  
  
property bList : {} –aList1とaList2を連結
  
  
property asEnable : {} –AS対応のアプリ一覧
  
property asDisable : {} –AS非対応のアプリ一覧
  
property infoNotPresent : {} –Info.plistが所定の場所に指定のファイル名で存在しないもの一覧
  
end script

set aList1 of spd to {}
set aList2 of spd to {}

set bList of spd to {}

set asEnable of spd to {}
set asDisable of spd to {}
set infoNotPresent of spd to {}

set apPath1 to (path to applications folder) as string
set apPath2 to (path to utilities folder) as string

tell application “Finder”
  –/Applications Folder
  
tell folder apPath1
    set aList1 of spd to (every application file) as alias list
  end tell
  
  
–/Applications/Utilities Folder
  
tell folder apPath2
    set aList2 of spd to (every application file) as alias list
  end tell
end tell

set bList of spd to (contents of (aList1 of spd)) & (contents of (aList2 of spd))

repeat with i in (bList of spd)
  
  
set aFilePosix to quoted form of POSIX path of i
  
set infoPath to aFilePosix & “Contents/Info.plist”
  
  
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)
  
  
if aRec = true then
    set the end of (asEnable of spd) to i
  else if aRec = false then
    set the end of (asDisable of spd) to i
  else
    set the end of (infoNotPresent of spd) to i
  end if
end repeat

return {length of (asEnable of spd), length of (asDisable of spd), length of (infoNotPresent of spd)}

–> {125, 235, 0}

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aPosix, findStr)
  
  
try
    set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  on error
    return 0 –エラー(指定のパスにファイルが存在しない)
  end try
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/22 指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック

指定のInfo.plistがバイナリモードであってもextractして、指定の文字列を含んでいるかどうかチェックするAppleScriptです。

先日掲載した「Script Editorで最前面のアプリの用語辞書を表示する」を実戦配備したところ……AppleScript未対応のアプリケーションもオープンできてしまいました。Scripting未対応アプリをScript Editorでバイナリ状態でオープンしてしまったりして、おかしな状態に。

オープン対象のアプリケーションがScriptableかどうかをチェックしてから処理しよう……とも思ったのですが、実際にSystem Events経由で調べてみると、「iBooks」などの非対応アプリまでプロセス情報を確認すると「Accepts High Level Events」がtrueになっています。

……というわけで、実際に各アプリケーションバンドル内のInfo.plistファイルのエントリを調べて、NSAppleScriptEnabledが入っているか(ちょっとこのあたり乱暴)どうかを調べるAppleScriptを書いてみた次第です。

スクリプト名:指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
set infoPath to choose file with showing package contents
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aFile, findStr)
  
  
set aPosix to quoted form of POSIX path of aFile
  
set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/17 Script Editorで最前面のアプリの用語辞書を表示する

Script Editorの「Script Menu」に入れて使っているものですが……最前面にあるアプリケーションのScript用語辞書をオープンするAppleScriptです。

OS X 10.9までは、AppleScriptエディタで指定のアプリケーションをopenすると用語辞書が表示されていましたが、10.10ではそのままの方法が通じなかったので、やり方を変えてみました。

Finderから指定アプリに対しScript Editorを指定してオープンするという……画像ファイルをPreviewで開くか、Photoshopで開くか……という小技の応用でなんとかしました。

スクリプト名:Script Editorで最前面のアプリの用語辞書を表示する
tell application "System Events"
  set frontProc to every process whose frontmost is true and visible is true
  
set aProc to contents of first item of frontProc
  
set aFile to file of aProc
end tell

set aFile to aFile as alias

–OS X 10.10でScript Editor側からアプリをオープンしてもダメだったので、Finder側からScript Editorで指定アプリをオープンすることに
tell application "Finder"
  set apFile to (application file id "com.apple.scripteditor2") as alias
  
open aFile using application file apFile
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/14 指定のstringsファイルをparseして返す

全アプリケーションバンドル中の各Localizable.stringsのエントリをパースして、FileMaker Proにキー値と各国語訳語のデータベースを作成するAppleScriptを作り、運用しています。

bundle0.png

できあがったデータベースで、自分のアプリケーション上で使いたい単語を検索、繁体字でも簡体字でもフランス語でも、そのままほぼコピペでローカライズができる環境を目指して作っていました。

locdb.png

自分がローカルにインストールしているアプリケーション数は、けっこう多いので……処理に時間はかかったものの、一晩Macで処理させておけば、問題ありません。

ところが、Apple製のアプリケーションで、Localizable.stringsではなくさまざまなstringsファイルに分けて翻訳(ローカライズ)してあるケースが多々ありました。

また、データベースに取り出した文字データが文字化けしている箇所が散見され(バイナリ圧縮形式のplistをそのまま読んでしまった模様)、当初のAppleScriptを大幅に書き直す必要が出てきたのです。

処理を根本から見直して……/usr/bin/plutilコマンドを使って(バイナリ、文字形式を問わず)stringsファイルを文字化してからパースするようにしました。

本AppleScriptは、その.stringsファイルを読み込んでパースする部分だけを抜き出したものです。

bundle1.png

実行すると、stringsファイルを選択するよう促されるので、アプリケーションフォルダ内の何らかのアプリケーションの、Contents/Resources/フォルダ以下の適当なlprojフォルダ内のstringsファイルを選択してください。

stringsファイルのエントリをparseして2Dのリストに入れて返してくれます。外で使う予定のなかったプログラム(ほぼ書き捨て)だったので、「動くには動くけれど、判定とかが乱暴」な感じにはなっています。

スクリプト名:指定のstringsファイルをparseして返す
set aFile to choose file of type {"com.apple.xcode.strings-text"} with showing package contents
set aRes to parseStringsAs2DList(aFile)
–> {{"TOOLBAR_PREFS_LOGS", "ログファイル"}, {"INSTALL_BUTTON", "インストール"}, {"TOOLBAR_PREFS_GENERAL", "一般"}, {"TOOLBAR_SCANLOG_TOOLTIP", "スキャンログを開く"}, {"PREFS_LOGGING", "ログ設定"}, …..}

–指定のstringsファイルをparseして返す
on parseStringsAs2DList(aFile)
  
  
set aPosix to quoted form of POSIX path of aFile
  
  
set a to (do shell script "/usr/bin/plutil -p " & aPosix)
  
set aText to paragraphs 2 thru -2 of a –頭と末尾の"{", "}"をスキップする
  
set bText to retArrowText(aText, "") –(↑)でリストになっているので、この機会に不要な改行にともなう空きアイテムを削除
  
  
set nList to {}
  
  
repeat
    
    
set aPos to offset of "\"" in bText
    
if aPos = 0 then exit repeat
    
    
set bPos to offset of "\" => \"" in bText
    
if bPos = 0 then exit repeat
    
    
set word1 to text (aPos + 1) thru (bPos - 1) of bText
    
    
    
set bbText to text (bPos + 5 + 1) thru -1 of bText
    
set cPos to offset of "\"" in bbText
    
    
set word2 to text (bPos + 5 + 1) thru (bPos + 5 + cPos - 1) of bText
    
    
set the end of nList to {word1, word2}
    
    
–処理終了をえっらく投げやりな方法で検出(もうちょっとなんとかしたい)
    
try
      set cText to text (bPos + 5 + cPos + 2) thru -1 of bText
      
copy cText to bText
    on error
      exit repeat
    end try
    
  end repeat
  
  
return nList
  
end parseStringsAs2DList

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/02 AppleScriptインハウス開発者の「現在からどの程度遅れているか」リスト

AppleScriptでの開発を行うユーザーは、たいていが開発専業の会社「ではない」ところで、1スタッフとして「開発も」行っているケースが多いようです。

そんなインハウスの開発者やスタッフと話をしたときに「外部の情報は知らないので、どの程度差があるか」が分らない、という話が出ました。

そこで、今日必要とされる各種技術の登場年から現在の年数を引き算して、各種要素技術をマスターしているかいないかで「何年ぐらい遅れているのでは?」という目安になるものを作ってみました。

マイナス10年+マイナス4年だったとして……合わせてマイナス14年ということではなく、大きい方の数字を目安にすれば(この場合、10年)よろしいでしょう。また、個別の業務や商品に関する知識、ノウハウについてはここでは言及しません。あくまで、個別の技術についてのみです。

これらの技術については、ご相談いただければお仕事として分りやすくレクチャーします。10年遅れていても、それを挽回するのに10年かかるわけではありません。

OS Xに移行している

OS Xを使っていないのは問題外。10.4より古いバージョンも問題外ですが、現在のところ実質的には10.6.8が下限というところでしょうか(10.4という説もありますが、10.5以前はつらすぎです)。

AppleScriptのプログラムを部品単位で分割して開発している

本Blogにも山ほど掲載していますが、まとまった機能を独立したルーチン(ハンドラ)として極力記述し、再利用性を向上させ……問題があった場合にはすぐに把握できる状態にしてあることは重要です。(マイナス20年)

他のマシン、他のユーザー環境でも動くScriptを書ける

これに配慮していないと、Mac OS X登場の2001年3月から進歩していないということになります。(マイナス13年)

他人にも読みやすいScriptを書く

個人で趣味で書いているScriptの中には、ループやサブルーチンを使わずに、ものすごく読みにくく書いてあるものがままあります。プログラム中にはコメントを入れ、コメントだけでは分りにくいものについては別途資料にまとめておく必要もあります。
仕事で書く以上は、他のスタッフにも読みやすいプログラムを心がけたいものです。(マイナス20年)

シェルコマンドをきちんと呼び出し、POSIX pathを扱える

Mac OS X的な世界観とUNIXの世界観の相互変換、相互呼び出しが行えないと、Mac OS X登場の2001年3月から進歩していないということになります。(マイナス13年)

Xcode上でGUIベースのAppleScriptアプリ開発が行える

Xcode上でAppleScriptによるGUIベース開発が行えるAppleScript Studioが提供されたのはMac OS X 10.2登場時(2002年)。年数でいえば、マイナス12年ですが……Xcodeに慣れているかどうかはScripterには死活問題であるため、Xcodeが使えない時点でかなり難しいと思います。(マイナス12年)

GUI Scriptingが使える

Mac OS X 10.3(2003年)で搭載されたGUI Scriptingは、通常のAppleScriptのやりかたでコントロールできない機能を強引にコントロールする「非常用手段」です。OSのバージョンアップを経て安定して利用できるようになってきましたが、多くのノウハウが必要です。(マイナス11年)

Adobeのアプリケーション以外のScriptが書ける

業務用のAdobeアプリケーションのScriptしか書けないのでは、「提案できること」「実現できること」の幅がきわめて狭くなります。Adobeアプリケーション以外の幅広いアプリのScriptingが必要です。(マイナス10年)

AppleScriptの自動記述の仕組みを持っている

AppleScript自体を解析してグラフ化したり、記述支援のための仕組みを持つことは、生産性の向上と大規模なプログラムの構築のために欠かせません。(マイナス8年)

Spotlightによるファイル検索が行える

ファイルシステムをバカ正直に再帰でたどっていくのはClassic Mac OS時代のファイル検索のやり方。Mac OS X 10.4(2007年)で搭載されたSpotlightをAppleScriptから利用して、任意のファイルを高速に検出するやり方は、もはや必須といっても過言ではありません。(マイナス7年)

オンラインアップデートの仕組みを構築できる

いったんユーザーに配布してしまったアプリケーションに不具合が見つかった場合に、オンラインアップデートによって強制的に更新することは、社内にツールを配布する場合でも重要な技術です。オンラインアップデート自体は難しいものではありませんが、幅広い知識が必要とされます。(マイナス10年)

Intel Macに移行している

PowerPCではなくIntel搭載のMacに移行していることは重要です。Intel移行によるパワーアップは必須のものといえるでしょう。(マイナス8年)

Sandbox対応のScriptが書ける

コードサインを使えて、Sandbox対応したAppleScriptが書けることは、今後のために重要です。Sandboxの機構はOS X 10.6(2008年)で採用されました。(マイナス6年、あるいは1年)

プログラムリンクによる他のマシンのコントロール

LAN上で他のMacのアプリケーションを制御する「プログラムリンク」は、複数のMacを1台のMacから制御する場合に必須の技術です。本技術はClassic Mac OSで長らく搭載されたものが、Mac OS Xに引き継がれました。(マイナス20年)

作成したアプリケーションに合わせたアイコンを作成できる

AppleScriptで作成したアプリケーションであっても、ユーザーに認識されやすいようにカスタムアイコンをつけておくことは重要です。アイコンの作成やRetina Display対応のアイコンの作り方など、簡単でありながらも適切なアイコンを作る技術には「なれ」が必要です。MacBook Pro Retinaの登場(2012年)からすでに2年あまりが経過しました。(マイナス5年)

インストーラーが作れる

Apple純正のツールInstaller Packager(10.6まで)や、Xcodeを用いてインストーラを作る必要があるケースもあります。設定ファイルなどをあらかじめ決められたフォルダに入れておく必要がある場合など、インストーラー形式で配布できるとユーザーへの負担を減らせます。インストーラーについては作成環境がかなりOSごとに変わってきたため、配布先のバージョンに合わせることも必要です。(マイナス6年)

AppleScriptObjCのプログラムが書ける

Xcode上でもAppleScriptエディタ上でもよいのですが、Cocoaの機能を直接使えるAppleScriptObjCは、使えると「できること」の幅が広がるでしょう。また、GUIベースのアプリをAppleScriptで作成する場合、現在AppleScriptObjCしか手段が提供されていません。(マイナス6年)

AppleScript Librariesを書ける

共有ライブラリの仕組みを理解し、共通部分をモジュール化する仕組み「AppleScript Libraries」を運用すると、チームで開発する際の生産性を向上できると思われます。(マイナス1年)

2014/07/02 PDFpenで任意のPDFをOCR処理(英単語だけ)

ドキュメントスキャナで紙から読み取ったPDFに対して、PDFpenの内蔵OCR機能を用いるAppleScriptです。

PDFpenにOCR機能が標準装備されていることは知っていたのですが、あくまで英語などの1バイト系(と書いてよいのか)の言語だけで、日本語は認識対象になっていません。

このため、PDFpenでOCR処理といわれてもさっぱり実用性を感じていなかったのですが、技術的な用語は英語でそのまま書いてあることもままあるため、完全な無駄……というわけでもない、という状態です。

たまたま海外のサイトを調べていたところ、PDFpenのOCR機能をAppleScriptから呼び出せることが分り、実際にプログラムを試し、実用性を持たせるために若干書き直してみました(海外のWebに掲載されているScriptは、ライターが書いた「実用性がいまいちなもの」も多々あります)。

ocr.png

スクリプト名:PDFpenで任意のPDFをOCR処理
–Webに掲載されていたサンプルを手直し
–■Automatically OCR Documents with Hazel and PDFpen
–By Katie Floyd
–http://katiefloyd.me/blog/automatically-ocr-documents-with-hazel-and-pdfpen

set theFile to choose file

tell application “PDFpen 6″
  close every document –安全のために記述。なくてもいい
  
  
open theFile as alias
  
  
tell document 1
    
    
ocr –PDFをOCR処理する(日本語は対象外)
    
    
repeat while performing ocr
      delay 0.2 –オリジナルはdelay 1だったが、長過ぎると判断
    end repeat
    
    
delay 1
    
    
close with saving
  end tell
  
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

PDFpenのAppleScript用語辞書を「ocr」で検索してみたところ、

ocr2.png

ocrコマンド、アプリケーションのperforming ocr属性、documentのneeds oct属性が用意されていることを見つけました。すでにOCR処理が行われて文字埋め込みが行われているかどうか、チェックできるようになっているので(さすがSmileSoftware!)、さらに書き足してみました。

かえすがえすも、日本語OCR機能がついていたら……

スクリプト名:PDFpenで任意のPDFをOCR処理 v2
–Webに掲載されていたサンプルを手直し
–■Automatically OCR Documents with Hazel and PDFpen
–By Katie Floyd
–http://katiefloyd.me/blog/automatically-ocr-documents-with-hazel-and-pdfpen

set theFile to choose file

tell application “PDFpen 6″
  close every document –安全のために記述。なくてもいい
  
  
open theFile as alias
  
  
tell document 1
    
    
set ocrFlag to needs ocr –文字埋め込みがすでに行われているとfalse、埋め込まれていないとtrue
    
    
if ocrFlag = true then
      ocr –PDFをOCR処理する(日本語は対象外)
      
      
repeat while performing ocr
        delay 0.2 –オリジナルはdelay 1だったが、長過ぎると判断
      end repeat
      
      
delay 1
      
      
close with saving
    else
      close without saving
    end if
    
  end tell
  
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2014/07/01 Parallels Accessを使ってiPadをリモートAppleScriptプログラミング端末に

コンピュータを持たずに自転車で出かけて、ふらっと入った喫茶店でいいアイデアを思いついて、プログラムを実際に書いて試したいと思うことがままありました(だったら最初からMacBook Airを持って歩けよ、というツッコミは当然なんですが)。

そのため、MacBook Airよりも非力でよいので薄くて軽いMac(のようなもの)が作れないものかと思い、いろいろ調べてみました。

img_2581.JPG

とくに最近、8インチのIntel Tablet(Windows 8)が手頃な値段で登場しはじめており、ハードウェア的にはほとんどMacもWindows PCも変わらないため、

  「8インチTabletの上でOS Xが動いたらいいのにな〜」

そんな動機から調べてはみたものの……ハイパワーなPCを組んでOS Xをインストールするという方向では世間的にノウハウがたまっている一方で、バッテリー動作のPC TabletにOS Xを入れて動かすのは、世間的にもノウハウがほとんどないことが分ってきました(それ以前に怪しい領域なので……)。

そんな折、仮想環境であるParallels Desktopをバージョン9にバージョンアップし、新機能についてひととおり確認を行っていたところ……なかなか面白い機能があることに(いまごろ)気付きました。

Parallels Desktop for Mac v9が標準搭載している機能で、リモートデスクトップ機能の「Parallels Access」というものが存在しています(Parallels Desktopと別アプリになっており、これだけインストールすることも可能)。以前の(自分はパスした)バージョンからこの機能が存在していることはうっすらとは覚えていたものの、それほど重視していませんでした。

このParallels Accessは、LAN内だけではなくネットワーク的に直接つながっていない場所にあるMacに対して、iPhoneやiPadからリモートアクセスするというものです(アクセスする端末、アクセスされる端末ともにインターネットにはつながっている必要がある)。

Team Viewerみたいなもの」といえば分りやすいでしょうか。

iOS用とAndoroid用にリモートアクセス端末アプリがあり、iOS用をApp Storeからダウンロード(フリー)して試してみました。

parallels_access.png

主にWindowsのアプリケーションをリモートで使うことを念頭に置いて開発されたParallels Accessですが、これが……Mac OS Xのネイティブ・アプリケーションもリモートで使えるようになっているのが面白いポイントです。

img_2576.JPG

img_2578.JPG

img_2579.JPG

img_2580.JPG

画面の小さいiOSデバイスからOS Xのアプリケーションを使うのは、物理的になかなかつらい(Air Serverでメニューの小さい文字に難儀したことが何度も)ものがありますが、iOSデバイスから使いやすいように、Parallels Accessでアクセス中にはOS X上のアプリを擬似的にシングルウィンドウで動かすようになっており、画面の解像度もiOSデバイス側に合わせて低く変更されます。

img_0673.PNG

デフォルトはシングルウィンドウモードですが、マルチウィンドウがそのまま表示/操作できるデスクトップモードもあります。

img_0676.PNG

つまり……OS Xが動くタブレットを無理矢理作って持ち歩くのではなく、OS Xにリモートアクセスできるタブレット(iPad mini Retina)を持ち歩いても同じことではないか、という話です。

iPad mini RetinaでデスクにあるMacBook Proにアクセスして、AppleScriptのプログラムを組んで試すようなことを実際に行えました。ストレスは……少ないほうだと思います。よくできています、Parallels Access。

Parallels Accessは、Parallels Desktop購入者には半年間のお試しアカウントが提供されているようです。購入者でなくても14日間のお試しが行えるとのこと(Parallels Desktopを持っていないと意味がないんですけれども)。

年間2,000円でParallels Accessを利用できるとのことで……月300円程度と考えると、なかなか納得の行きそうな価格に思えます。

半年のお試し期間中に、iPhone 5経由でインターネットにテザリング接続しているiPad miniで、毎月どの程度のデータ転送量になるのか試しておきたいところです(盛大にデータ転送を行われると、テザリング契約そのものが7GB制限にひっかかって、本当に使いたいときに使えないことに、、、)。

「快適さ」はひたすらネットワーク接続速度に依存するため、「あくまで緊急用」という位置付けになるかもしれません。ただ、風呂に入っている最中に防水ケースに入れたiPadからMacの中に入っているラジオ録音ファイルを聞く……とかいう使い方だとけっこう合っている感じがします(音声もリモート端末側に出力されるので)。

Parallels Accessに問題があるとすれば、複数台のモニタをつないでいるマシンにアクセスs中はすべてのディスプレイがミラーモードで同じ内容が表示され、接続解除したあとのディスプレイ解像度は元に戻るものの、ウィンドウ配置などは「元通り」……とはいかないため、マルチディスプレイ持ちにはちょっと気持ちが悪いというところでしょうか。