smellman's Broken Diary

クソみたいなもんです

PyObjC + Xcode

Using PyObjC for Developing Cocoa Applications with Python というドキュメントを見つけたので、早速試してみたらちょいとはまったのでメモ。環境は以下の通り。

まず最初にビルドができなくてはまった。これは単純にXcodeがPython2.3を呼び出してしまっているために発生していた(.bash_profileの内容は無視されてしまう)ので、ビルドの設定を書き換える事で対応をします。Xcodeの プロジェクト->アクティブターゲット'Development'を編集 を選択してカスタムビルドコマンドのビルドツールを /usr/bin/env から /Library/Frameworks/Python.framework/Versions/Current/bin/python に変更します。単に setup.py を呼び出しているだけですので、このような設定でよいでしょう。
次にはまったのは実行時に以下のような例外が発生するケースでした。

2006-11-25 17:53:37.965 PyAverager[1112] Unknown class `Averager' in nib file, using `NSObject' instead.
(略)
  File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/PyObjC/PyObjCTools/AppHelper.py", line 235, in runEventLoop
    main(argv)
KeyError: 'NSUnknownKeyException - [<NSObject 0x1332840> valueForUndefinedKey:]: this class is not key value coding-compliant for the key calculatedMean.'

Averagerクラスが見つからないため、結果としてキーが見つからずあぼーんしているという状態でした。ただ、Xcode上で Python Class 作っているのになぜ?と思いこんでしまいかなり解決に時間がかかりました。
この問題は Pythonmac-SIG xcode problems に解決のヒントがありました。ここで、次のような記述があります。

So the nib (whatever that is) cannot find the class Averager.
By going to the source of PyAverager I noticed that the Averager module is imported indirectly, as in:

for pythonModule in info[u'Modules']:
__import__(pythonModule)

If I do "import Averager" or "__import__('Averager')" after these lines the application runs successfully. So I guess that info[u'Modules'] doesn't contain 'Averager'.

PyAveragerのモジュールを読み込むところでAveragerを読むように細工をしているんですが、そもそもforループで読み込まれていれば問題がないはずです。というわけでXcodeのよーくみてみるとすごい間抜けな事をしているのに気づきました。Averager.py が"その他のリソース"扱いになっていたんです(涙 XcodeのグループとファイルにあるAverager.pyをClassesのフォルダの中に入れてビルドをしたらあっさり動きました(号泣
ちなみに、Classesのフォルダの中に入れるとはドキュメントのどこにも書いてなかったです。Classesフォルダを選択した状態で、新規ファイル->Cocoa->Python Class を選ぶとちゃんと Classesフォルダの中に入った状態で作られるので、これははまる人とはまらない人がいそうだ(汗