2006-12-05
目次
「Wonderful Server Life」 第29回 田畑 英和
〜AFP編〜
前回新しいXserveの紹介をしましたがまずはその補足から。新型のXserveはLOM(Lights-out Management)と呼ばれる機能を搭載しています。この機能を使えばリモートからXserveの電源を入れるなどのリモート制御ができます。実際にこの機能を利用するにはLOMに対応したソフトウェアが必要になりますが、つい最近アップデートされたApple Remote Desktop v3.1はさっそくこのLOMをサポートしています。
さて、話を元に戻してネットホームの設定方法を解説しましょう。これまでAFPサービスや共有ポイントの設定方法を解説してきました。これでAFPを使ってクライアントコンピュータからサーバ上の共有ポイントにアクセスし、ホームをクライアント上ではなくサーバ上にもつことができるようになりました。
ですが、ネットワークホームを利用するにはさらにネットワークマウントの設定も行う必要があります。ネットワークホームを使う場合、ユーザのログイン後ただちにホームが使える必要があります。ですのでいちいちログインしてからサーバ上のホームを手動でマウントするといったことはできません。そこで自動的にサーバ上の共有ポイントをマウントする必要があるわけですが、これがネットワークマウントになります。
◇ネットワークマウントの設定
ネットワークマウントの設定は「ワークグループマネージャ」を使用します。ツールバーから「共有」をクリックし、まずは画面左側に表示される共有ポイントのリストからネットワークマウントを設定したいフォルダを選択します。ネットワークホームの設定を行うには共有ポイントのリストから「Users」を選択します。つまりサーバ上の「/Users(/ユーザ)」をネットワークマウントするように設定します。
次に右上の「ネットワークマウント」ボタンをクリックします。ネットワークマウントの設定を行うにはディレクトリの管理者として認証を行う必要があります。これはマウントレコード(ネットワークマウントの設定情報)をディレクトリサービスで管理するためです。つまり設定したマウントレコードは共有ディレクトリ(LDAP)の中に書き込まれます。共有ディレクトリに対して書き込みを行うので、ディレクトリの管理者としてまずは認証を行う必要があるわけです。
認証を行うには「場所」ポップアップメニューの右側のカギをクリックします。「場所」のポップアップメニューですが、ここでマウントレコードを書き込む場所を選択します。OpenDirectoryとAFPサービスを同一のサーバ上で運用する場合はデフォルトの「LDAPv3/127.0.0.1」のままでかまいません。
負荷分散のためにOpenDirectoryとAFPサービスを別々のサーバで運用する場合は、まずAFPサービスを稼働させるサーバをOpenDirectoryサーバに「ディレクトリアクセス」を使ってバインドしておきます。こうすればAFPサーバ上で「ワークグループマネージャ」を使ってネットワークマウントの設定を行うときに「場所」ポップアップメニューにOpenDirectoryのサーバがリストアップされ、マウントレコードの保存場所として選択することができます。
適切な場所を選択したら次に「この共有ポイントのネットワークマウントを使用する」のチェックを入れます。ネットワークマウントのプロトコルを選択できますが、今回はMac同士でファイル共有を行いますので「AFP」を指定しておきます。
「用途」は「ユーザのホームディレクトリ」を選択します。用途の選択でクライアント上のどこに共有ポイントがマウントされるかが決まります。
以上でネットワークホームのためのネットワークマウントの設定が完了しました。最後に画面右下の「保存」ボタンをクリックするとOpenDirectory上にマウントレコードが書き込まれます。
・ネットワークマウントの設定
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_Mount_03.png
ディレクトリサービスを使ってサーバにアクセスするように設定済みのクライアントは、サーバ上(OpenDirectory上)に書き込まれたマウントレコードを読み取って自動的に共有ポイントをマウントします。
以上がネットワークマウントの設定方法です。それでは、次回は各ユーザごとのホームの設定とホームディレクトリの作成について解説します。
つづく
藤本裕之のプログラミング夜話 #104
前回まではもっぱら受け身、データをドラッグ&ドロップされる側のやり方を解説してきたわけだが、普通にアプリケーションを開発していればもちろん逆の送り側、すなわちドラッグの出発点になりたい局面も生じるわけ。世の中はやはりギブ&テイクなんであって、財布を落とす不幸なひとがいるからそれを拾う幸運なひとが生じるのである。……もちろん世の中にはちょっとエレベータのボタン押すだけで15,000円も稼いぢゃう広告代理店のヒトとかそういうのもいるわけなので、イマイチ例えが説得力を欠くような気がしないでもないが、まぁ俗世間はどうか知らぬがプログラムはそうありたいもんですな、と。
あるビューが自分自身や他のビュー、はたまた他のアプリケーションに対して提供しうるデータを持っていて、その受け渡しをドラッグ&ドロップで可能にしたいとする。既に我々はこうしたデータを受け取る術を知っているので、送り出し側がやるべきシゴトも容易に想像がつくはずだ。すなわち、ドラッグが始まったらデータをドラッグ用のペーストボードにセットしてやればいい、のである。以下にビュー上でドラッグが始まったらやみくもに「Data to be dragged」という文字列を送り出すという全く実用性のないサンプルを示す。
@implemantation MyView
- (void) awakeFromNib { /* わしは文字列をドラッグするよ、と宣言 */
[self registerForDraggedTypes:
[NSArray arrayWithObject:NSStringPboardType]];
}
- (void)mouseDown:(NSEvent*)theEvent {
_dragging = NO; /* これはインスタンス変数 */
}
- (void)mouseDragged:(NSEvent*)theEvent {
if(_dragging == NO){ /* まだドラッグしてなければ... */
NSString* toBeDragged = @"Data to be dragged";
NSPasteboard* pb =
[NSPasteboard pasteboardWithName:NSDragPboard];
[pb declareTypes:
[NSArray arrayWithObject: NSStringPboardType] owner:self];
[pb setString:toBeDragged forType:NSStringPboardType];
NSImage* anImage =
[[[NSImage alloc] initWithSize:
[toBeDragged sizeWithAttributes:
[NSDictionary dictionary]]] autorelease];
[anImage lockFocus];
[toBeDragged drawAtPoint:NSMakePoint(0,0)
withAttributes:[NSDictionary dictionary]];
[anImage unlockFocus]; /* ドラッグするイメージを作成 */
[self dragImage:anImage
at:[self convertPoint:
[theEvent locationInWindow] fromView:nil]
offset:NSMakeSize(0,0) /* Tiger以降は無視する */
event:theEvent
pasteboard:pb
source:self
slideBack:YES]; /* そのイメージをセットする */
_dragging = YES; /* ただいまドラッグ中 */
}
}
/* この他、- (id)initWithFrame:frameRect: とか - (void)drawRect:とか
必要なメソッドはちゃんと定義されてあるものとする */
@end
これしきのこと、と思えば大層なコードに見えるがクラシックシステムのときのドラッグ&ドロップのインプリメントを考えれば「ホントにこんだけでいいの?」というくらい簡単になったんである。それでは最初から解説を……と思ったが、もう所定の行数ではないか。中途半端になるのも困るので解説は次回。上のリストの再録はしないので(してたら毎回ほんの少ししか進めない)、その気のあるひとは取っておくこと。
(2006_12_01)
高橋真人の「プログラミング指南」第102回
〜カプセル化について(1)〜
こんにちは、高橋真人です。
今までクラスという仕組みを使って、「機能を持ったデータの固まり」としてのオブジェクトの片鱗を見てきました。しかし、そもそもプログラムというのは詰まるところコードの固まりであって、「それがオブジェクトというまとまりを持ったからといって、何が面白いんだ?」という疑問を持たれる方もいらっしゃることと思います。
連載の96回では、オブジェクトを利用するメリットの一つとして「処理の詳細を隠してしまえる」というお話を少ししました。今回は、この話をもう少し広げていきたいと思います。
最近、私が仕事で取り組んでいるものの一つにMLTEがあります。MLTEは、2000年にTextEditの制約を打ち砕く新しい技術として登場した仕組みです。TextEditには32kの壁などという有名なものから始まり、テキスト編集の仕組みとして登場してから随分経ったため、時代遅れになった部分が数多くあり、足りない部分はすべてプログラマが一つ一つ組み込んで行かなければならなかったのです。
そんなTextEditの置き換えとして登場したMLTEの機能についてかいつまんで紹介しますと、日本語のインライン入力、テキストのドラッグアンドドロップ、複数の書体・サイズ・カラーの混在した表示などを最初からサポートし、テキスト編集はもちろんのこと、無限回数のアンドゥやリドゥなども標準で備えているのです。
私が仕事で作っているアプリケーションの一つに、ずっとPowerPlant(*注)で作ってきたものがあります。最初のリリースは2000年で、Mac OS 9用のアプリでした。
ユーザーの環境が徐々にOS Xに移行してきたのに合わせ、Carbon化を行い、細々とした機能追加要求などを受けてメンテナンスを続けていますが、この度少し大きなユーザーからの要求があったため、Cocoaによる作り直しも含めいろいろな対策を検討しました。
結果として作り直しは見送ったものの、OS Xでしか使われない今となっては意味がなかったり無駄だったりする部分も少なくないため、内部設計の一部変更も含めていろいろと手を入れていたのです。
そのアプリにはテキスト編集エリアがあって、ここはこのアプリのUIの中では中心になる部分なので、それなりにしっかりと作り込む必要があります。もともとはPowerPlantのLTextEditViewというクラスに若干の拡張を加えて実現していました。しかし、PowerPlant自体が日本語編集で抱える問題点や、私自身の拡張のやり方のまずさなどから、ちょっとしたバグも抱えていたため、この際思い切ってこれをLMLTEPaneという、PowerPlantがMLTEを使うために用意したクラスを利用することとしたのです。
LMLTEPaneは、PowerPlantの末期に加えられたクラスです。その後間もなくPowerPlant自体のバージョンアップが止まってしまったためPowerPlantによって加えられた機能はごくわずかですが、MLTE自体が持つ高機能な仕組みはそのまま利用することができるので、開発の手間はある程度削減できると踏んだのです。
しかし、問題がなかったわけでもありません。LTextEditViewから作った私のクラスでは、保持するテキストの長さを表示する仕組みがありました。ユーザーが文字編集するのを受けてリアルタイムで文字数を表示します。
リアルタイムな文字数表示という場合、日本語では変換中の文字数も拾う必要があります。ユーザーによっては、一度に大量の文字を入力したままで変換作業を行う場合もあるからです。
また、ユーザーからの追加要求として、このテキストフィールドでは改行を含むいくつかの文字が入力できないようにする必要がありました。
これらの機能は残念ながらMLTEを「そのまま」使っているだけでは実現ができないのです。
文字数表示に関しては、いろいろ調べて解決できました。InputMethodは、処理の途中でいくつかのCarbonイベントを発行します。よって、アプリケーションでこれらのイベントを捕まえることによって、InputMethodがまだアプリケーションに渡していない(現在変換処理中の)文字列の情報を得ることができるのです。
しかし、もう一つの問題は難物です(「難物でした」と過去形になっていないのは、今現在でも完全解決に至っていないからです・涙)。InputMethodを介して渡ってくる文字列や、ペーストによって渡されてくる文字列に関しては、同様にCarbonイベントなどによって捕まえることができます。ところが、MLTEが提供しているドラッグアンドドロップの仕組みによって渡ってくるテキストの場合、イベントを通して捕まえることができないのです。
さんざん調べた挙げ句に見つけた答えは、以下のようなものです。
・MLTEが用意しているドラッグアンドドロップのハンドラ(処理関数)をオフにする
・MLTEに代わって、自分でドラッグアンドドロップのハンドラを実装する
この技術を勉強したことのある人はご存知でしょうが、ドラッグアンドドロップを実装するには、二種類の処理をしなければなりません。
一つはモノをつかんでドラッグを始める処理。グラフィックアプリケーションであれば図形を、Finderであればアイコンを、テキスト編集ソフトであれば選択したテキスト範囲をユーザーがマウスでつかんで動かし始める時に、「ドラッグオブジェクト」を作成し、ドラッグの動作を起動する処理です。
もう一つは、ユーザーがドラッグによって引っ張ってきたドラッグオブジェクトに反応し、マウスボタンが放されたらそれを受け入れる(または拒否する)処理。
厳密に言えば、後者もさらに二つの処理に分けられるのですが、まあそれはよしとしましょう。
しかし、MLTEに対して「ドラッグアンドドロップのハンドラはこっちでやるからね」と伝えるためのフラグを立てると、何故かこの二つの処理を両方ともやめてしまうのです。
私としては、単にドラッグされてきたデータを受け入れた時にだけ(つまり拒否した場合にはいちいち知らせてくれなくていい)、それを教えてくれさえすれば充分なのに、ドラッグ関係の処理を一斉に放棄してしまうって、一体どういうことなんでしょ?
この事実を知った時に私はショックの余り、しばらくは何も手に付きませんでした(笑)が、嘆いていても事態は何も動きませんから、ちまちまと必要な処理を組み込んで行きました。
しかーし、Tiger上では問題なく動く処理が何故かPanther上では怪しい動作になるというバグのせいで、いまだにその回避策をめぐって右往左往を余儀なくさせられている私なのであります。(悲しいかな、未だユーザー環境も開発環境もPantherがメインであります)
ちょっと、個人的な感情が絡んでしまったために、少し脱線してしまいました(笑)が、現実にアプリケーションを作っている人の悶々とした日常の一シーンが少しは伝わりましたでしょうか?
「カプセル化の話をする」と言っておいて、単なる仕事の愚痴を連ねたにすぎないと思われた方も多いかもしれませんが、心配はご無用。ちゃんとこの話を元にカプセル化ということについての考察を進めてまいります。
ただ、行数が多くなりましたので、この続きは次回に。
注:PowerPlantは、Metrowerks社のCodeWarriorの一部として提供されていたC++言語によるアプリケーションフレームワークです。Mac OS 9の時代には多くの商用アプリケーションで利用され、Carbon対応もなされたために、Mac OS Xになってからもしばらくは使われていましたが、もともとの設計がCarbonイベントモデルではない古いイベントモデルに合わせてあったため、Mac OS X用に全面的に書き換えた新しいフレームワークであるPowerPlant Xとしてさらに発展するはずでした。
しかし、2005年のAppleのインテルプラットホームへの移行により、MetrowerksとCodeWarriorが終焉を迎えてしまったため、実質的に入手することはできなくなってしまいました。
ただ、今年の頭にPowerPlantとPowerPlant Xはオープンソースになったため、CodeWarriorのIDE(これは、もはや入手不可能)なしでも使うことができるようになる日が来るかもしれません。もっとも、最初からMach-OであるPowerPlant Xはまだしも、PowerPlant自体をXcode対応にさせるのは、そうそう簡単なことではないような気がしますが。
ニュース・解説
今週の解説担当:小池邦人
● Carbon ドキュメント & サンプル & SDK ナビゲーション(2006/12/01)
【開発環境】
使い始めてかなり時間が経つと言うのに、Xcodeのテキストエディタでソースコードを編集していると、今でも大変ストレスがたまります(涙)。テキストファイルのオープンが遅いとか、Framework APIの文字色が変えられないなどの機能的な不備も多いのですが、バグなのか仕様なのか、とにかくソースコードを編集しているとイライラする事に数多く出くわします。
複数ファイルの検索と置換がうまくいかないケースが多々あります。検索位置がズレルのです。ソース内に日本語コメントを入れているからという噂もありますが、1ファイル内の検索と置換では問題が出ません。また、失敗したファイルを一度ファイル保存してやるとケロッと直るので、バグのような気もします?
数値をダブルクリックすると、カンマを挟んだ隣の数値まで選択してしまいます。これは、カンマを金額の3桁区切りと判断しているのが原因だと聞いたのですが、ソースコードエディタにそんな機能必要ないですよね(笑)。引数や配列の羅列でカンマの左右にスペースを入れない作法の私としては、まことに情け無い仕様です。
ソースコードの一部をカットする場合、行のセレクションの仕方により、前行のCR(キャリジリーターン)までカットしてしまう場合があります。これも、ソースコードの編集では余計なお世話です。複数行をマウスで選択してカットする場合には、前行のCRが消えてしまうと、後方の行が連続して表示されてしまい(インデントが消える)再度CRを入れなくてはいけなくなります。また、カット部分の先頭にCRが入っていると、ペースト後にも余分な編集が必要となります。
まだまだ色々とあるのですが…Metrowerks CodeWarriorのテキストエディタを利用している時は、こんなにもストレスは溜まりませんでした。Apple社の技術者は平気で使っているのかな? それとも、さっさとエディタ部を差し替えているのかな? Xcode 3.0ではいくらかマシになっているのを祈りましょう。もしくは、上記問題の解決方法をご存じの方は、ぜひお教えくださいませ(エディタを代えるという手段以外で…)。
【テクニカルドキュメント】
前回から12月1日の期間中、Apple社のGuidesサイトとReferenceのサイトには新規登録はありませんでした。そのかわり、デベロッパ向けの読み物がひとつ登録されています。CoreGraphicsに含まれるImageIO Frameworkの各ルーチンとそのサンプルソースコードが解説されています。今まで色々な画像ファイルフォーマット(JPEGやTIFFなど)をオープンする場合には、QuickTimeのImageCompression関連のルーチンを利用していたのですが、ImageIOルーチンを利用すると各社デジタルカメラのRAW画像フォーマットもオープンできるようです。ドキュメントには、Mac OS X 10.4.8でオープン可能な画像ファイルフォーマットの一覧も掲載されています。ただし、どの画像フォーマットが読み込めるかについては、Mac OS Xのバージョンに随分と依存するようなので注意が必要かもしれません。それにしても、テクニカルノートとして登録されても良さそうな内容ですね。
「Using the ImageIO Framework with Mac OS X 10.4 Tiger」(読み物)
http://developer.apple.com/graphicsimaging/workingwithimageio.html
前回から12月1日の期間中、新規テクニカルノートはひとつも登録されませんでしたが、新規テクニカルQ&Aの方は6つ登録されました。テクニカルQ&Aについては、前号で木下さんが解説されていますので、そちらも参照してみてください。
QA1496「Configuring the Recent Searches menu for NSSearchField」(初版)
QA1497「FSDeleteObject fails with fBsyErr, sometimes」(初版)
QA1500「Debugging a Web Kit Plug-in in Xcode」(初版)
QA1387「Integrating With The Connect to Server Dialog」(初版)
QA1499「Security Framework Error Codes」(初版)
QA1390「Standard Audio – The CodecSpecificSettings- Array and MagicCookie properties」(初版)
http://developer.apple.com/technicalqas/index-rev-date.html
【サンプルソースコード】
前回から12月1日の期間中、Apple社のSample Codeサイトには、サンプルソースコードが3つ登録されました。
「SetMouseAcclSample」(HID&Cocoa関連)(初版)
「MovieAssembler」(FinalCutPro関連)(初版)
「tcplognke」(Network関連)
http://developer.apple.com/samplecode/index-rev-date.html
【デベロップメント SDK】
前回から12月1日の期間中、Apple社のSDKサイトには新しいSDKがひとつも登録されませんでした。
http://developer.apple.com/sdk/
◇MOSAからのお知らせと編集後記は割愛します◇