2010年6月28日月曜日

自作アクションでエラーを返す

AppleScriptObC で書いた Automator の自作アクションでエラーを返すには、次のようにやればよいようです。

script ErrorTest
  property parent : class "AMBundleAction"
  property NSDictionary : class "NSDictionary"
 
  on runWithInput_fromAction_error_(input, anAction, errorRef)
    my fatalError(-1750, "your own error message", errorRef)
    return missing value
  end runWithInput_fromAction_error_

  on fatalError(errorNum, msg, errorRef)
    set objsArray to {errorNum, msg}
    set keysArray to {current application's OSAScriptErrorNumberKey, current application's OSAScriptErrorMessageKey}
    set contents of errorRef to NSDictionary's dictionaryWithObjects_forKeys_(objsArray, keysArray)
  end fatalError
end script

errorRef は NSDictionary のポインタのポインタなので、contents of を使って、作ったオブジェクトを渡すところがキモです。

エラー番号 -1750 は MacError.h に errOSASystemError と宣言されていて、それを使うのがベストです。AppleScriptObjC の定数参照の要領で、current application's errOSASystemError とか書いてみたのですが、だめでした。MacError.h は CarbonCore のヘッダファイルなので、Carbon Framework をリンクしてみたのですが、やはりだめでした。

情報をお持ちの方がいらっしゃいましたら、コメントをください。

2010年6月24日木曜日

iPad × Apple Wireless Keyboard

iPad で Apple Wireless Keyboard (JIS) を使ってみました。iPad と Wireless Keyboard のペアリングは iPad に表示されたパスコードをキーボードから入力し、特段問題なく完了しました。

キーボードをつなげてうれしいのは、キー配列がいつも通りなこと、カーソルキーが使えることです。Shift キーを押しながらカーソルキーを操作すると、テキストが選択状態になります。この状態で、Command + X / C / V でコピペもできます。Command + A の全選択、Command + Z の Undo も効きます。長いテキストも、ソースコードすらストレスなく入力できます。サードパーティ製のキーボードでは、JIS 配列として認識しないなどのトラブルが報告されていますが、Apple 製のキーボードは大丈夫なようです。

日本語変換はクセが強く、特に補完機能のせいで、必要ない文字まで入力されてしまうことが多いです。かなりアホな辞書なので、辞書登録機能が待ち遠しいです。ことえりは Control + K でカタカナ変換だったと思いますが、この手のショートカットキーにも対応して欲しいです。ATOK 風に Control + I にも変更できれば完璧です。

バッテリの消費は早いです。Bluetooth キーボードを操作してスリープからの復帰もできるので、頻度は低いながら、常時通信しているのは間違いないでしょう。

スリープ復帰後、4桁のパスコード入力も Bluetooth キーボードから行えます。これはこれで便利なのですが、ちょっと危険かもしれない、と思いました。Bluetooth キーボードはペアリングする必要があるのでまだよいのですが、Dock タイプのキーボードからも同様にスリープ解除できるとしたら、パスコードのブルートフォースアタックで簡単に破られてしまう可能性もあります(Dock タイプのキーボードを装ったデバイスを作るのは簡単ですし、ブルートフォースアタックの自動化も簡単です)。iPad には、パスコードを10回間違えたらメモリを消去する設定がありますが、これをオンにしておく方がよいと思います。

2010年6月22日火曜日

iBooks 1.1 と自炊本事情

iPhone用の iOS 4 と iBooks 1.1 がリリースされ、iBooks でも PDF が閲覧できるようになりました。iPad 用の iOS 4 はまだですが、iBooks の新バージョンは iPad でも今日から使用できます。ようやく純正アプリで、所謂「自炊本」の PDF を閲覧できるようになりました。

早速試してみると、EPUB の本と違って、PDF の閲覧時はページをめくるアニメーションはありません。単に横にスワイプするだけで、やや味気ない感じです。しかも、スキャンをしただけの自炊本は結構もたつきます※。解像度や元の本の大きさなども関係あるかもしれませんが、文庫本で試してみても、若干もたつく感じです。TeX などからコンパイルして作った PDF はスムーズにページ送りできますが、ちょっとごちゃごちゃした図が貼ってあるページは、やはりもたつきます。

普通に本を読み進めるときは、文庫本サイズの本であれば、若干もたつくものの問題ありません。A4 くらいの本だと、かなりひっかかりを感じます。パフォーマンスについては、ページを先読みするなどの手法を導入して改善されるかもしれません。ざーっとページを送ってみたいという要求に対しては、かなり難あり、という印象です。

PDF の表示速度で比較すれば、CouldReaders などの同様の機能を持つサードパーティー製アプリと大差ありません。ファイルを転送するという観点で言うと、iTunes で PDF ファイルを「本」と認識させて iPad と同期できる点では iBooks が優れており、閲覧という観点では、CouldReaders は縦書きの本などに対応するために、ページ送り方向を変更できる点が優れています。

※ ScanSnap を使って、ファインモード (カラー 200dpi / 白黒 400dpi 相当, SnapSnap 仕様) でスキャンしています。()

関連記事

自炊ケーススタディ: マンガ週刊誌編

2010年6月20日日曜日

Automator アクションでの子プロセスの扱い

Automator のアクションで子プロセスを走らせたとき、子プロセスを管理するのはアクション側の責任になります。Automator のワークフローはユーザの操作によって停止することがありますが、その場合、子プロセスを終了させるのは、アクションの実装者の責任です。

AppleScriptObjC で自作アクションを書けますが、ナイーブに do shell script を使って子プロセスを起動させると、停止させる術がありません。NSTask を使って自分で管理するのが良さそうです。

ユーザの停止操作によって、AMAction から継承した stop メソッドが呼ばれますので、そこで動いている子プロセスを停止させます。テンプレートとしては、こんな感じでしょうか。

script my_Automator_Action

  property parent : class "AMBundleAction"
  property NSTask : class "NSTask"
  property NSFileHandle : class "NSFileHandle"
  property task : missing value
 
  -- @override
  on runWithInput_fromAction_error_(input, anAction, errorRef)
    ...
    set command to POSIX Path of "..."
    set args to {}
    set the end of args to "argument 1"
    set the end of args to "argument 2"
    ...
    my runExternalTask(command, args)
    ...
  end runWithInput_fromAction_error_

  -- @override
  on |stop|()
    if task is not missing value then
      task's terminate()
    end if
  end |stop|
 
  -- Instead of 'do shell script', use this method to prepare for abortion by user operations.
  on runExternalTask(command, args)
    set nulldev to NSFileHandle's fileHandleWithNullDevice()
    set task to (NSTask's alloc)'s init()
    task's setLaunchPath_(command)
    task's setArguments_(args)
    task's setStandardInput_(nulldev)
    task's setStandardOutput_(nulldev)
    task's setStandardError_(nulldev)
    task's |launch|()
    task's waitUntilExit()
    task's autorelease()
    set task to missing value
  end runExternalTask

end script

気付いた点をいくつか。

  • NSTask の setArguments: は NSArray を受け取ることになっていますが、以下のようにAppleScript の文字列のリストをそのまま渡しても問題ないようです。ただし、リストの中に数値などが入っていた場合、自動的に文字列に変換してくれず、エラーになります。
  • 標準出力と標準エラー出力を /dev/null へつないでおかないと、コンソールに全部出てしまいます。
  • do shell script は一旦シェルを経由するので、リダイレクトやパイプの指定ができます。同様のことを行うには、NSPipe や NSFileHandle 等を使って自力でやるか、一旦シェルを呼び出すようにします。
  • do shell script は標準出力の内容を戻り値として取得できますが、NSPipe を使って自力で取得する必要があります。

iPadで仕事をしてみる

セミナーに参加する機会があったので、ノートをとるのにiPadを使用してみました。

iPadの標準メモアプリを縦位置で使いました。縦位置ではキーボードがやや狭いので、使いにくいかと思ったのですが、特にストレスなく使えました。タッチパネルに指で触れるだけなので、キータイプの音がしないので、静かな会場ではよいと思います。机の上に iPad をべたっと置いて使うと、暗い会場では下から顔が液晶バックライトで照らされる格好になるので、もしかすると異様な光景になっているかもしれません。

日本語の変換精度が悪く、iWork などのレビューでも散々に書かれています (iWork は全然関係ないですが…) 。iOS 4 ではユーザ辞書登録機能が追加されるなどのロードマップが示されているので、今後、改善されていくものと思います。

2010年6月18日金曜日

VLC は諦めて HandBreak にします

しばらく前に、VideoLAN、OSX版VLCプロジェクト終了の危機 - 開発者不足が原因と報じられていましたが、いよいよこれが現実のものになったようです。VLC 1.0.6 がリリースされていますが、Mac OS X 版のバイナリは一向に公開されません。

VLC は巨大なソフトウェアで、ソースコードから自分で make するのは途方もなく大変です。正直、そこまでやる元気はないです。

また、私が使用していた VLC 1.0.3 から 1.0.5 までMPEG4-AAC エンコーダのバグ (※) で、音が割れるという障害が発生していましたが、これも一向に修正される気配がありません。

※ 同一の .ts ファイルから MPEG2 Video + MPEG Audio の設定で MPEG2 プログラムストリームを生成したときは、音は割れませんでした。

生 .ts を保存し続けるには HDD の容量が厳しくなってきたので、これからはHandBreak というソフトでエンコードすることにします。日本語版もあります。コマンドライン版も配布されているので、こちらを使えば Automator を使ってエンコードできます。

HandBreadkCLI は /usr/local/bin にインストールされているものと仮定します。以下のようなサービスを Automator で作って、「iPhone 用にエンコード」とでも名前を付けて保存しておきます。

以下はコピペ用のコードです。お好みで、ビットレートをいじるなり、2パス解析をやらせるなりしてください。

HANDBRAKE=/usr/local/bin/HandBrakeCLI
SIZE='--width 480 --height 272'
VIDEO='--format m4v --vb 896'
AUDIO='--ab 128 --arate 48'
FILTER='--deinterlace slow'
ENCODER='--encoder x264 --aencoder faac'
X264_OPTS="--x264opts 'level=30:cabac=0:ref=2:mixed-refs=1:analyse=all:me=umh:no-fast-pskip=1'"

while [ $# -gt 0 ] ;
do
    FN=`basename "$1" .mpg`.m4v
    DIR=`dirname "$1"`
    cd "$DIR"
    $HANDBRAKE $ENCODER $VIDEO $X264_OPTS $SIZE $AUDIO $FILTER -i "$1" -o "$FN" \
        > /dev/null 2> /dev/null
    shift
done

2010年6月13日日曜日

iPad 在庫あったー!

品薄が続いているiPadですが、幸運にも予約なしで購入することができました。16GB WiFiモデルです。

使い方については、まだこれといったアイデアはないのですが、一応、持ち歩くことを想定しています。結局、iPhoneも同時に持ち歩くので、音楽やムービーはiPhoneに任せることにしたので、iPadの容量は16GBで十分と判断しています。MacBook Airを持ち歩かないで一週間くらい過ごす、というのもやってみたいと思います。

地鎮祭として、例によってパワーサポートのアンチグレアフィルムを貼り、保護ケースを付けました。ケースは BELKIN の Grip Vue クリアを選びました。背面と周辺部分を覆うタイプのものです。Apple 純正ケースのような、二つ折りのタイプのものも考えたのですが、横向きでは使いにくいのではないか、という懸念が払拭できず、やめました。

まだ必要なアプリが出揃ってない感じです。とりあえず、iOS 4 のリリースを待ちたいと思います。

2010年6月9日水曜日

WWDC 2010 の感想

Apple の WWDC 2010 が開催中です。大方の予想通り iPhone 4 が発表されました。これまで iPhone の弱点と言われていた、マルチタスク機能、液晶解像度、電池の持ちなどを改良し、より魅力的な端末になりました。一番驚いたのは、値段です。このスペックで 32GB モデルが $299 は安い。ガラパゴスケータイ陣営の皆様はどうするんでしょう、本当に。

Safari もアップデートされました。Safari 5 になって、より軽くなりました。意外なことに Flash アプリも軽くなりました。Flash プラグインは 10.0r42 のままなので、Safari 側で何かがんばったのでしょう。それでも処理や内容に比べて CPU を占有しすぎの感は拭えませんが…。

一番ショックだったのは Mac 本体や次期 Mac OS X について、何のアナウンスもなかったことです。新型 MacBook Air を期待していたのに…。

以上、WWDC 2010 に対する感想でした。