2009-09-23

iPhone OS上のPyObjCアプリのボトルネック

PyObjCはPythonで手軽にアプリを開発するのにはとても良いのですが、iPhone/iPod touch上では起動にとても時間がかかります。

ちょっと調べてみたところ、常に使われる、"import objc" と "obj.loadBundle ("UIKit",...)" のコードの処理に、それぞれ約3秒かかっていることが分かりました。
Python自体は遅くないのですが、PyObjCを使用するための初期化の処理に5秒以上かかってしまいます。

また、PjObjCはとても大きなライブラリなので、メモリ容量の面からも不利です。
例えば、ネイティブのMobileAddressbook.appは5.7MBなのに、HelloPythonは11MBにもなります。
このことから、メモリのオーバーヘッドが5MBほどもあることが分かります。

いずれのオーバーヘッドもPyObjCとUIKitを使用したとき固有のものです。

[English version]

2009-09-22

私の気付いたiPhone 3.1の変更点

自分のiPod touchをiPhone OS 3.1.1に上げました。
以下が私の気付いた変更点ですが、良い面と悪い面があります。
  • パスワード解析バグへの対処
    パスワード入力フィールドを、一文字消し、シェイクしてUndoすると、その文字がエコーバックして見えてしまう問題がありました(気になる、記になる...の記事Neowin.netの記事)。この問題は3.1ではきっちり対応され、Undoした文字はエコーバックされなくなりました。これはとても良い改善点です。
  • ミュージックアプリ (iPodアプリ) が起動していないと、ホームボタンのダブルクリックで [iPodコントロール] を呼び出せない
    以前紹介した、ビデオPodcastをバックグラウンドで聞く裏技が使えなくなってしまいました。同じ操作をゲームの音量調整のためも使っていたのですが、こちらもだめになりました (iPod touch first generation)。
    以前はホームボタンをダブルタップすると、いつでもポップアップの [iPodコントロール] を呼び出せて、音量調整や再生、停止、早送りを行えていたのですが、iPhone OS 3.1では、音楽の再生中しか、呼び出せません。音楽を再生していない状態では、ホームボタンのシングルクリックと同じで、実行中のアプリが終了してしまいます。
    これは、とても困ります。
    (ちなみにホームボタンの設定は、[一般] の [ホーム] にあります。)

あなたの大切なiPhone/iPod touchを即座にロック : Passcode Lock Now

iPhone/iPod touchのパスコードを長くして、パスコードロックを強化する対策を以前紹介しました。
多くの人は、パスコードの設定と一緒に [パスコードを要求] するまでのタイマーを設定して、短い時間の間に自動ロックされても、再度パスコードを入力しなくても良いようにしていると思います。
これが結構不安で、同期の最中など、iPhone/iPod touchを置いてその場を離れなければならないようなケースには、他の人にあなたのiPhone/iPod touchがパスコードなしでのぞき見られてしまう恐れがあります。
この不安を解消するために、パスコードロックを即座に行うアプリを作成しました。
PasscodeLckNw (Passcode Lock Now) (build #001 2009-09-22) [Download]

インストールの仕方
  • App Storeからはインストールできません。
  • 上記キットをiPhone/iPod touchに適当な方法でmobileユーザのホームディレクトリなどにコピーします。
  • iPhone/iPod touchにログインして、rootユーザになります(suコマンドなど)。
  • unzipコマンドで、/Applications/ フォルダの配下に展開します。
    cd /Applications/ ; unzip ~mobile/PasscodeLckNw-001.zip
  • respring コマンドを実行して、iPhone/iPod touch に新しいアプリを認識させます。
仕組み
  • 久しぶりのシェルスクリプトアプリです。
  • SpringBoard プロセスをkillallしています。リブートするよりはずっと早く、確実にパスコードロックすることができます。

2009-09-08

Snow Leopard/Leopardでメモをよりお手軽に作成

iPhone/iPod touchのメモアプリはすぐに呼び出せて、とっさにメモがとれて便利です。
それに比べてMac OS Xのメモはまだまだ冷遇されています。
Mailを立ち上げて、メモボタンあるいは、メニューから [新規メモ] を選ばなければなりません。
メモをとりたいのにメールを開くという、心理的な変換がバリアとなってしまいます。

そこで、ワンクリックでメモアイテムを作成して、入力状態にする方法を考えました。
こうすることで、Mac OS X 上のメモ機能の地位も少しは上がると思います。
iPhone/iPod touchのメモと(何らかの方法で)同期している場合は、連携して使えて便利さ倍増です。

とても初歩的なAppleScriptです。
Macの [アプリケーション] フォルダの [ユーティリティ] の [AppleScriptエディタ] を開いて、以下のスクリプトをコピペします。
そして適当な名前で [ファイルフォーマット] を [アプリケーション] として保存します。
そのアイコンをドックに置けば、ワンクリックでメモを作成できます。
tell application "Mail"
activate
end tell
tell application "System Events"
tell process "Mail"
-- click the menu item "New Note" of the menu "File" of menu bar 1
click the menu item "新規メモ" of the menu "ファイル" of menu bar 1
end tell
end tell
アイコンを設定したい場合の方法は次のようにします。
右上の画像(など)を適当な名前のファイルに保存し、プレビューアプリで表示して、全てを選択(cmd-A)したのち、画像をコピー(cmd-C)します。上で作ったアプリをファインダで選択し、 [情報を見る cmd-I] して、表示されたウィンドウの中のアイコン画像をクリックした状態で、ペースト(cmd-V)します。
(本当は、全て設定済みのAppleScriptアプリを作りたかったのですが、AppleScriptアプリパッケージの中のicnsリソースを入れ替える方法が見つからなかったので、このような手動手順の紹介となりました、すみません。)

[English version]

Snow Leopardのメールアプリのメモ機能の仕様変更

Snow Leopard (Mac OS X 10.6)のメモ機能(Note of Mail.app)の仕様が変わっているようです。
(正確にはLeopardを再インストールして確かめなければなりませんが。)
  • メモアイテムはNotesフォルダにないと認識されなくなりました。
    IMAPサーバでも、ローカルフォルダでも同じです。
    いずれもメールアプリからは隠されて見えませんが、右クリックメニューから呼び出せる [アカウント情報を見る] ではちゃんと「メモ」(Notes)フォルダが表示されます。
    (なお、To Doはカレンダに保存されるようです。)
  • 以前(Leopard)はどのフォルダにあってもメモ一覧に統合して表示されていたはずですが、遅いのでやめたのでしょう。
  • 逆に、Notesフォルダにあれば、通常のメールアイテムもメモ一覧に表示されます。

2009-08-30

Snow LeopardのExposéのGrid表示

Snow LeopardのExposé
グリッド配置される (約60アプリ)
LeopardのExposé
(有名な150アプリ表示)
前者の2.5倍あるが個々のウィンドウを区別しやすい
Snow Leopard (Mac OS X 10.6) のExposé (Expose) の表示がグリッド配置に変更されてしまいました。
私はTigerやLeopardの表示スタイルの方が好きです。
グリッド配置には次に挙げるような欠点があると思います。
  • 全てのウィンドウが同じサイズにそろえられてしまうので、目的のウィンドウを探しにくい。
    例えばSafariの大きなウィンドウとステッキーズの小さなウィンドウが同じ大きさになってしまうので一見して区別しにくい(右の図でもSafariの大きめのウィンドウがどれなのか見つけられない)。
  • ウィンドウの大きさという情報が欠落する。
  • グリッド配置事体にあまり意味がない。
    グリッド配置は一見整理されて表示されいるように見えますが、元々のウィンドウの並びがアナログ的なのを無理矢理直線的にしているのでかえって分かりにくい。
  • 画面上の無駄な隙間が多くなり、個々のウィンドウの表示がさらに小さめになってしまう。
  • 何より、面白みが少なくなってしまった。
ぜひとも、元のような表示モード(グリッド配置OFF)も復活してほしいものです。

[English version]

Snow Leopardのプロセス一覧;64bitだらけ

Snow Leopard (Mac OS X 10.6) のプロセス一覧を見てみると、ほとんど64 bitプロセスです。
個人向けパソコンもいよいよ本格的に64bitの時代になったことを実感しました。

2009-08-23

今日の気になるPodcast;Macを使いこなそうGarageBand編、iPod touchゲームギャラリー

2009-08-19

Blogspot/Bloggerで、よりお手軽に投稿 その2

以前、Bloggerの投稿ページをブックマークしておくと、Tumblrのブックマークレットと同じようにワンクリックでBloggerに投稿できて便利、という小ネタを書きました
でも、その方法では、ブラウザの今見ているウインドウが投稿ページに置き換わってしまって、Tumblrと同じように、とはいきませんでした。
単純にURLをブックマークするのではなく、Javascriptで一工夫することで、別ウィンドウでの投稿が出来る方法が分かりました。
  1. まず、Bloggerの投稿ページをブックマークします。
  2. ブラウザのブックマークの管理ツールを開きます。
  3. URLが http://www.blogger.com/post-create.g?blogID=xxxx になっていることを確認します。
  4. このURLの前に以下を挿入します(最後のシングルクォートを忘れずに)。
    javascript:void(window.open('
  5. URLの最後に以下を挿入します。
    ',null,'width=750,height=700,scrollbars=yes'))
  6. 結果として下記となっているかを確認します。
    javascript:void(window.open('http://www.blogger.com/post-create.g?blogID=xxxx',null,'width=750,height=700,scrollbars=yes'))
よろしければ、お試しください。

[2009-08-29] scrollbars=yes を追加

2009-08-18

メモ同期アプリ Notes Upload Build #004

iPhone OS 2.0以降で動作しなくなっていたメモ同期アプリ(旧バージョン)が、iPhone 3.0でやっと復活の日を迎えることができました。
前回はJiggyという独自のGUIツールを使用していましたが、今回はXcodeでGUIを作成しました。
DB操作やネットワークアクセスには前回と同様、Pythonスクリプトを使用しています。

メモ同期 Notes Upload (build #004 2009-08-18) [Download]

できること
  • メモアプリのエントリをIMAPプロトコルで、メールのフォルダに同期(現バージョンではアップロードのみ)します。同期先のメールフォルダはあらかじめメールソフト(メーラー)で作成しておいてください。
  • 無線LAN (Wi-Fi) 接続で同期を行えます。
  • GUIは今回は英語のみです。
  • Last Uploadの日時を指定して、部分的な同期(新しいエントリのみ)ができます。同期完了後、Last Uploadの日時は自動的に更新されます。
  • 今回はプログレスバーをつけてみました。
インストールの仕方
  • 事前にPythonをCydia等でインストールしておいてください。パッケージ名「iPhone/Python」を選ぶと必要な周辺パッケージも一度にインストールできて便利です。
    tar (Tape Archive) も必要なのでインストールしてください。
  • 上記キットをiPhone/iPod touchに適当な方法でコピーします(いったんPC/MacにコピーしてからscpでiPhone/iPod touchにコピーする、など)。ファイル名は NotesUpload004.tar.gz です。
  • iPhone/iPod touchにログインして、rootユーザになります(suコマンドやsudo shコマンド)。
  • iPhone/iPod touchの /Applications/ フォルダ配下に展開します(/var/mobile/Applications/ ではありません)。念のため、コマンドは下記です。
    cd /Applications/ ; tar xzvf ~mobile/NotesUpload004.tar.gz
  • コピーしたアプリをiPhone/iPod touchに認識させるためにrespringまたは再起動します。
お願い
初めて作ったXcodeアプリなので、まずは、動いたかどうか(正常に起動したらPreference画面が表示されます)をお知らせいただけると、とてもありがたいです。
自分の環境では動いていますが、それがそのまま他の環境で動くかどうかが全く分からないからです。
よろしくお願いします。

(noets.dbの内容を読み込んでIMAPにエントリを作るだけで、削除処理は全く行わないアプリなので、安全に実行していただけます。ただし、業務等重要な用途で使用することは今の段階では避けてください。)

開発後記
Pythonスクリプトを使用しているのは、とても容易に使えるIMAPライブラリを利用したいがためです。
Pythonにはあらかじめ何でもそろっています(Batteries included;バッテリも入っています(おもちゃなどがバッテリ付きで、他に何も買いそろえなくても、すぐに遊べるようになっている状態をたとえにしている))。
今回が初めてのXcodeプログラミングだったのですが、Objective-CおよびCocoa Touch独自のお作法に、最初確かに、めげそうになりました。
(なお、App Storeに登録していませんので、iTunesで探しても見つかりません、念のため。)

iPhone 3.0のnotes.dbの変更点

iPhone/iPod touch 3.0のメモアプリ (MobileNotes.app) のsqlite3テーブルスキーマが1.1の頃に比べて拡張されています(2.xからかもしれません)。
$ sqlite3 notes.db
sqlite> .tables
Note
_SqliteDatabaseProperties
NoteChanges
note_bodies
sqlite> .schema
CREATE TABLE Note (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, creation_date INTEGER, title TEXT, summary TEXT, contains_cjk INTEGER, modification_date INTEGER, author TEXT, content_type INTEGER);
CREATE TABLE NoteChanges (record INTEGER, type INTEGER);
CREATE TABLE _SqliteDatabaseProperties (key TEXT, value TEXT, UNIQUE(key));
CREATE TABLE note_bodies (note_id INTEGER, data, UNIQUE(note_id));
CREATE TRIGGER delete_note_bodies AFTER DELETE ON Note
BEGIN
DELETE FROM note_bodies WHERE note_id = OLD.ROWID;
END;
sqlite>

変更点は、
  • Notesテーブルの追加カラム:
    contains_cjk:cjk文字が含まれているかどうか。1でYes。漢字の有無でフォントが切り替わる謎がこれで解けた。
    modification_date:最終修正日時。1.1ではcreation_dateでmodification_dateを代用していた。
    author:おそらく、Sync時にサーバ側のFrom:ユーザがストアされる。
    content_type:不明。メモアプリで作ったアイテムは、全て0のようだ。
  • 追加テーブル:NoteChanges
    アイテムを編集したり削除した履歴。編集の度にレコードが追加される。おそらく、type=1は編集、type=2は削除。Syncすると履歴が削除されると思われる(後で実験)。

2009-08-15

iPhoneシミュレータでのアプリの実行環境

  • $USER:Mac OS Xのログオンユーザ
  • $PWD:/
  • $HOME:/Users/$USER/Library/Application Support/iPhone Simulator/User/Applications/$UUID/
  • アプリのUUIDはXcodeでビルドして実行するたびに変化する
  • $HOME配下にあるもの:Documents/、Library/、tmp/、appl.app/
[2011-05-14] 2009年に記事を書いてからXcodeを更新していない (3.1.3) ので、いまは変わっているかもしれませんが...
  • シミュレータでのユーザのホームディレクトリは、
    ~/Library/Application\ Support/iPhone\ Simulator/User/
    この下に、Media や Library や Applications がある。
  • シミュレータでのファイルシステムのルートは、
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulatorX.Y.sdk/
    例えばこの下の Applications にi386用にビルドした? アプリをコピーして実行することもできる。
  • シミュレータ本体の起動は、
    open "/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app"