2006-02-07
目次
「WebObjects Dev Report」 第38回 田畑 英和
今回は「ビジネスマッチングシステム」で実際に使用している、小ワザをいくつか紹介したいと思います。
■改行の表示
「ビジネスマッチングシステム」ではユーザの情報を複数行のテキストで入力するような箇所がありますが、複数行のテキストを表示する場合は注意が必要です。
複数行のテキストを単純にWOStringにバインドして表示しようとしても改行が無視されてWebブラウザ上に表示されてしまいます。WOTextを利用して表示してもよいのですが、ここでは改行付きの文字列をWOStringに表示する方法を紹介します。
・文字列の改行を
タグに変換するコード
public static String stringWithBR(String value) {
if (value != null) {
value = WOMessage.stringByEscapingHTMLAttributeValue(value);
value = NSArray.componentsSeparatedByString(
value, "
").componentsJoinedByString("<BR>");
}
return value;
}
このコードでは引数に指定した文字列(value)に含まれる改行コードを、
タグに変換しています。まずWOMessageのメソッドを利用して制御コードや記号をエスケープした文字列に変換しています。
このとき改行コードは”
”という文字列にエスケープされます。そして次に”
”を<BR>に置き換えています。<BR>グへの置き換えにはNSArrayのメソッドを用いています。いったん文字列を”
”で区切ってArrayに変換してから、今度は<BR>タグでArrayを1つの文字列に連結しています。
このようにすれば最終的には改行が<BR>に変換された文字列を取得することができます。つまり、次のような変換が行われます。
・変関例
MOSA -> MOSA
WebObjects -> MOSA<BR>WebObjects
WebObjects
このような変換をおこなった文字列をWOStringにバインドするとWebブラウザ上に複数行の文字列が表示されます。このときWOStringのescapeHTMLアトリビュートはfalseに設定するのを忘れないでください。
■プライマリーキーの取得
モデルの定義でEntityのプライマリーキーをPropertyとして指定しなかった場合は、直接プライマリーキーの値を取得することはできません。もちろん、Propertyとして指定するという方法もありますが、EOFではプライマリーキーの管理は自動的に行われますので、通常はPropertyには指定しません。
それでも、プライマリーキーの値を取得したい場合は次のようなコードで取得することができます。
・プライマリーキーを取得するコード
public Number primaryKey() {
NSDictionary primaryDict = EOUtilities.primaryKeyForObject(
editingContext(), this);
if(primaryDict != null) {
return (Number)primaryDict.objectForKey("mosaUserId");
}
return null;
}
このコードはカスタムEOのクラスファイルに実装してあります。他の方法でもプライマリーキーを取得することができますが、ここではEOUtilitiesを用いたコーディングを行っています。
まず、プライマリーキーを取得するEOが属しているEditingContextと、EOをprimaryKeyForObject()メソッドに渡してNSDictionaryを取得しています。このDictionaryの中にプライマリーキーが格納されています。プライマリーキーはEntity内に1つだけとは限らないため、このような形式になっています。
Dictionaryから実際のプライマリーキーを取得するには、プライマリーキーのアトリビュート名(この場合はmosaUserId)を指定して値を取り出しています。
今回紹介した方法ではEOUtilitiesクラスを使用していますので、eoaccessパッケージをimportするのを忘れないでください。また確定したプライマリーキーを取得するには、あらかじめEOがデータベースに保存されている必要があります。
■EOEntityのUserInfoの取得
EOModelerでモデルを作成するときに各EntityにUserInfoを設定することができます。任意のEntityを選択してInspectorを開き、Inspectorの一番右側のボタンでEOEntityのUserInfoを設定できます。
EOModeler上で設定したUserInfoはプログラムからアクセスすることができます。
・EOEntityのUserInfoを取得するコード
public Object userInfoValueForKey(String key) {
EOEntity entity = EOUtilities.entityForObject(
editingContext(), this)
NSDictionary userInfo = entity.userInfo();
return userInfo .valueForKey(key);
}
このコードもカスタムEOクラスでの実装になります。まずEOUtilitiesクラスのentityForObject()メソッドでEntityを取得します。次に、EOEntityクラスのuserInfo()メソッドを用いてUserInfoを取得します。
UserInfoはDictionary形式になっていますので、あとはNSDictionaryのメソッドを使ってkeyを指定することによりUserInfoの値を取得することができます。これでモデル上で設定しておいた値をプログラムから利用できるようになります。
小池邦人のCarbon API 徒然草(2006/01/20)
前回から、本サンプルアプリケーションのUniversal Binary化(Intel x86 CPU対応)について解説していますが、今回は、開発環境の移行作業についての話です。サンプルアプリケーションの開発用プロジェクトを、Metrowerks CodeWarrior 9.6からXcode 2.2へと移植してみます。
記述を短くするため、これからは、Metrowerks CodeWarrior 9.6をMWCと、Xcode 2.2をXcodeと記載します。なにゆえ最新のMWC 10でなく9.6を使うかと言うと、それにはあまり深い意味はありません(笑)。筆者が、今でも9.6を使い続けており、まだ10への移行をしていないためです(所有はしていますが…)。たぶん、現状で大きなトラブルが発生しないかぎりは、筆者はMWC 9.6を使い続けるでしょう。残念ながら、これが実用の最終版ですね。ただし、これからする話は、10に対しても有効だと思われますので、MWC 10を利用しているユーザの方も参考にしてください。
もちろん、開発プロジェクトをMWC用からXcode用へ移植する作業を、すべて手作業で実行しても問題はありませんが、Xcodeのファイルメニューにある「プロジェクトの読み込み…」機能を利用するのが一番簡単で便利でしょう。手順は以下の様になります。
1.Xcodeファイルメニューから「プロジェクトの読み込み…」を選択
2.一覧リストから「CodeWarriorプロジェクトの読み込み」を選択
3.「次へ」ボタンをクリックで画面を切り換える
4.右上にある「選択…」ボタンをクリック
5.ファイル選択ダイアログで対象となるMWCプロジェクトファイル(.mcp)を選択
6.空だったカラムにCodeWarriorプロジェクトのパスと名称が設定される
7.「CodeWarriorから”グローバル・ソースツリー”を読み込む」をチェック
8.「参照プロジェクトを読み込む」をチェック
9.「完了」ボタンをクリック
10.AppleScriptによる制御でCodeWarrior IDEが起動され移植作業が開始される
11.MWCプロジェクトファイルと同階層に.xcodeprojファイルが作成される
この作業の大前提は、先んじてMWC側でアプリケーションをコンパイル&リンク(Make)可能なプロジェクトを正しく作成しておくことです。ちなみに、7と8の行程で行うチェックボックスの選択は、プロジェクトの移植方法によってはオプション操作となります。
上記移植処理には、CodeWarrior IDEに実装されているAppleScript機能を使いますので、IDEが起動できない環境では(MWCを所有していないと)実行できません。こうして完成したXcode用プロジェクトですが、最小の追加処理ですぐに使えるように、先んじてMWC用プロジェクトの方で準備しておく作業が幾つかあります。まあ、これについてはユーザの考え方や好みも関係するのですが、筆者の場合には、以下の処理を事前に実行しています。
まず最初に、nibファイル、リソースファイル、アイコンファイルなど、アプリケーションパッケージのResourcesフォルダに入るファイル類は、プロジェクトファイル(.mcp)と同階層にResourcesフォルダを作り、あらかじめその中にまとめて入れておきます。また、Info.plistファイルの構築に.plcファイルを使うのは止め、単独ファイルとして作成し、プロジェクトファイルと同階層に保存しておきます。そして最後に、Xcodeのプレフィックスヘッダ用として、以下内容を記述したテキストファイルを作っておきます。
#include <QuickTime/QuickTime.h>
例えば、MWC用プロジェクト名が「MOSA.mcp」ならば、プレフィックスヘッダファイルの名称は「MOSA_Prefix.pch」とし、プロジェクトファイルと同階層に保存します。
今回の作業でMWC用プロジェクトから移植したXcode用プロジェクトは、以下のサイトに「MOSA_10.4_UB.zip」という名称で登録されています(MWCとXcodeどちらからでもMake可能)。MWC用プロジェクトの設定内容と、フォルダ内に保存されているファイル構成については、こちらもぜひ参照してください。
http://www.ottimo.co.jp/library/index.html
移植処理を完了すると、MWC用プロジェクトに登録されているソースファイル、ヘッダファイル、nibファイル、リソースファイル、LibraryやFrameworkなどは、すべて自動的にXcode用プロジェクトに登録されます。ところが、IDEのPackageタブで設定しておいたアプリケーションパッケージの中身は、リソースファイルとnibファイルを除いて、まったく移動してくれません。例えば、今回のサンプルアプリケーションでは、以下の4つのファイルやフォルダが移動されません。
1.English.lprojフォルダとその中身のInfoPlist.stringsテキストファイル
2.Japanese.lprojフォルダとその中身のInfoPlist.stringsテキストファイル
3.MosA.icnsアイコンファイル
4.MosD.icnsアイコンファイル
また、せっかく作成し保存しておいたInfo.plistファイルも、Xcode側では有効となるように設定されていませんので注意してください。加えて、プレフィックスヘッダファイルのMOSA_Prefix.pchについても、Xcode側で登録作業をしないと有効になりません。
次回は、MWC用プロジェクトの移植作業において、Xcode側でしなければいけない追加処理について解説したいと思います。Info.plistやMOSA_Prefix.pchのプロジェクトへの登録や、SDKの種類の選択、コンパイルオプションの設定などを行います。
つづく
SqueakではじめるSmalltalk入門 第55回 鷲見 正人
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。SqueakのMorphic GUIでは、ウインドウやメニューなど目に見えるものはすべて「モーフ」と呼ばれるオブジェクトで構成されています。今回は、身近なウインドウとメニューについて、たしかにこれらがモーフであることを、前回のモーフの共通操作の復習をかねて確認してみましょう。
▼ウインドウをモーフとして扱う
SqueakシステムのMorphic GUIにおいてウインドウは、タイトルバーのドラッグによる移動や、クローズボタンよる「閉じる」操作など、Macライクな操作が可能なように作り込まれています。しかし一方で、ウインドウはモーフでもあるので、コマンドクリックによる選択やハローによる属性の変更といった、前回のMorphのインスタンスと同様の操作も受け付けます。
Morph allSubclasses includes: SystemWindow ” => true ”
SystemWindow allSuperclasses includes: Morph ” => true ”
デスクトップメニュー → 開く… → ワークスペースなどの操作で、適当なウインドウを開き、まず、ウインドウ内の適当な場所で、コマンドキーを押しながらドラッグしてみてください。ウインドウはモーフとして選択され(自分用のハローを表示)、マウスポインタの動きに追従するはずです。タイトルバーを使わずともこうしてモーフであるウインドウを移動することができます。
[fig.A]モーフとして選択されたウインドウ
http://squab.no-ip.com:8080/mosaren/uploads/55a.png
「コマンドドラッグ」といえば、OS 9以前からあって、OS Xでも使えるTIPSのひとつに「ウインドウのタイトルバーをドラッグする際にコマンドキーを押しておくと、そのウインドウをアクティベートせずに移動できる」という操作があるのをご存じでしょうか。Morphic GUIにおけるコマンドドラッグによるモーフの移動は、他のモーフとの前後の位置関係を変えないので、ウインドウに用いたならば、くだんのTIPSと似た効果が期待できそうですね。
選択時にモーフを囲むように現れるハローの機能も見てみましょう。左上の×印(ピンク色)ハローは、ウインドウをモーフとしてゴミ箱に移動します。他のモーフと同様に、ゴミ箱から取り出すことも可能です(ゴミ箱をダブルクリック)。Squeakシステムの設定が「モーフをゴミ箱に移動せずにただちに削除する」モードに設定(Preferences disable: #preserveTrash、または、ヘルプ… → プリファレンス → morphic → preserveTrash のチェックをオフ)されている場合は、ピンク色ハローは、ウインドウのクローズボックスとまったく同じ働きをします。
黄色ハローについても、ウインドウの右下隅をドラッグして行なうサイズ変更と同じ働きをします。もちろんウインドウには、四隅と上下左右の境界のドラッグという、もっと柔軟なサイズ変更のためのUIが作り込まれているので、わざわざこの黄色ハローを使う必要はありません。ここでは、他のモーフと同様に大きさを変えることも可能であることを確認できればよいと思います。右上の緑色ハローは、ウインドウをモーフとして同じものを複製します。
それがどんな役に立つのかは不明ながらも、見ていてとても楽しい機能が青色ハローによるウインドウの回転です。ウインドウは回転した後も、文字の入力や編集を通常どおり行なえます。ペイント系に対する、ドロー系の図形オブジェクトの特徴として「回転操作を行なうことができる」点を挙げることがありますが、ウインドウの回転は、まさにドロー系オブジェクトであるモーフにより作られたウィジェットならではの「お遊び」ではないでしょうか。
[fig.B]モーフとして回転させたウインドウ
http://squab.no-ip.com:8080/mosaren/uploads/55b.png
▼ポップアップメニューとメニュー項目をモーフとして扱う
ポップアップメニューもウインドウ同様、自身もモーフであり、かつ、さらにメニュー項目といった「部分」もモーフにより構成されています。たとえば、デスクトップをクリックしてポップアップするお馴染みの「デスクトップメニュー」(別名「ワールドメニュー」)も、ポップアップ後、メニュー項目を選択する代わりに、コマンドドラッグによる移動が可能です。
[fig.C]モーフとして選択、移動中のメニュー
http://squab.no-ip.com:8080/mosaren/uploads/55c.png
青色ハローによる回転も可能です。ウインドウ同様、回転してもメニューとして機能し続けます。
[fig.D]モーフとして回転しても機能し続けるメニュー
http://squab.no-ip.com:8080/mosaren/uploads/55d.png
メニューを選択してからさらに、適当なメニュー項目を改めてコマンドクリックすると、その項目をモーフとして選択できます。
[fig.E]モーフとして選択されたメニュー項目
http://squab.no-ip.com:8080/mosaren/uploads/55e.png
この状態で、たとえば黒色ハローでピックアップしたり、緑色ハローで複製を作って特定のメニュー項目を独立して取り出すことが可能です。こうして取り出したメニュー項目は、たいてい、もとのメニューで選択したときと同じ挙動を保持していますから、たとえばデスクトップメニューの「開く…」のように、頻繁に使用するメニュー項目があれば、その複製を作ってデスクトップに置いておくのもよいかもしれません。
[fig.F]取り出した「開く…」メニュー項目
http://squab.no-ip.com:8080/mosaren/uploads/55f.png
この「メニュー項目」モーフに限らず、ウインドウのタイトルバーやスクロールバー、さらにその中にあるパーツ類もすべてはより細分化されたモーフで構成されています。このように、他のモーフに組み込まれて、その部品として機能するモーフのことを「サブモーフ(submorph)」と呼びます。次回はこのサブモーフ化という機構について、もうすこし掘り下げてみましょう。
バックナンバー:
http://squab.no-ip.com:8080/mosaren/
ニュース・解説
今週の解説担当:木下 誠
———————————————————————-
Shark 4の紹介
———————————————————————-
Developer Toolsをインストールすると、XcodeとInterface Builderに加えて、色々な開発用ユーティリティも付いてきます。その中にあるSharkをご存知でしょうか? 鮫のアイコンが怖いですが、アプリケーションのパフォーマンスを最適化するためのツールです。CPUの使用状態、メソッド呼び出しのトレース、仮想メモリの状態など、様々な項目の確認ができる、非常に高機能なソフトです。
そんなSharkの機能の一部を紹介するドキュメントが公開されています。「Optimizing Your Application with System Trace in Shark 4」です。このドキュメントでは、システムコールの呼び出しや仮想メモリのフォールトの頻度をチェックするための機能「System Trace」と、任意のポイントでイベントを記録するための「Sign Posts」を解説しています。
Sharkは非常に高機能なので、使ったことが無い方は、ぜひ一度試してみてください。
Optimizing Your Application with System Trace in Shark 4
http://developer.apple.com/tools/performance/optimizingwithsystemtrace.html
———————————————————————-
FireWire SDK 21が登場
———————————————————————-
FireWire SDK 21が登場しています。紹介文によると、Universal Binaryへの移行を助けるための改良が含まれるそうです。
Development Kits
http://developer.apple.com/sdk/
———————————————————————-
ドライバのためのUniversal Binary化設定
———————————————————————-
これもドライバ周りの話題になります。I/O Kitのカーネルドライバに向けた、XcodeでのUniversal Binaryのための設定を解説したドキュメントが公開されています。「TN2163: Building Universal I/O Kit Drivers」です。
Xcodeでの、ターゲットアーキテクチャ、使用するSDK、コンパイラのバージョンの設定などが解説されています。ドライバ開発者ではない方でも、10.4以前のMac OS X向けのXcodeの設定など、参考になるところがあります。
TN2163: Building Universal I/O Kit Drivers
http://developer.apple.com/technotes/tn2006/tn2163.html
———————————————————————-
QuickTime Audio APIのドキュメント、サンプル
———————————————————————-
このところ非常に力の入っているQuickTime関連のドキュメントやサンプルの公開ですが、今週もあります。QAが1つと、サンプルが2つ、公開されました。今週は、Audio APIの強化週間のようです(?)
QA1459: QuickTime Audio – Easy Frequency Level Metering with
MovieAudio APIs
http://developer.apple.com/qa/qa2005/qa1459.html
ExtractMovieAudioToAIFF
http://developer.apple.com/samplecode/ExtractMovieAudioToAIFF/ExtractMovieAudioToAIFF.html
SillyFrequencyLevels
http://developer.apple.com/samplecode/SillyFrequencyLevels/SillyFrequencyLevels.html
MOSAからのお知らせと編集後記は割愛します