MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第234号

2006-12-26

目次

  • 「「Wonderful Server Life」   第32回 田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • SqueakではじめるSmalltalk入門  第76回  鷲見 正人
  • ニュース・解説               木下 誠

「Wonderful Server Life」  第32回  田畑 英和

  〜Leopard Server Preview編〜

 さて、2007年はいよいよLeopardがリリースされます。これまではMac OS XとMac OS X Serverが同時にリリースされていましたので、これまでと同じであればLeopardと同時にLeopard Serverもリリースされることになるでしょう。

 WWDC直後に一度Leopard Serverについては簡単にレポートしていましたが、来るべきLeopard時代に向けて、現在公開されている内容をもとにあらためてLeopard Serverについてレポートいたします。
 Leopard Serverがリリースされても、安定して稼働しているサーバはなかなかアップデートをしにくかったりもしますが、Mac OS X Serverが付属するXserveの場合はおそらく早い段階で付属するOSもLeopard Serverに移行していくものと思われます。ですので新規にサーバを構築するとなると、Leopard Serverを使い始めるのもわりと近い将来かもしれません。

□管理ツール
 セットアップを行う「サーバアシスタント」が新しくなり、新しい管理ツールとして「Server Preferences」が導入されます。「Server Preferences」はちょうど「システム環境設定」のサーバ版のような外見をしており、次のような項目の管理を行う事ができます。

・アカウント
  ユーザ、グループ
・サービス
  カレンダー、iChat、ファイル共有、Mail、Webサイト
・システム
  information、Backup

 また、サーバの状態を確認するためのDashboardウィジェットが付属し、各サービスの稼働状況やディスク、ネットワーク、CPU、メモリの使用状況を一目で確認することができます。
 「ディレクトリアクセス」の改良版と思われる「Directory Utility」というツールも付属します。

□iCal Server

 新しいサービスとしてカレンダーサーバが搭載されます。カレンダーサーバを利用することにより、ネットワーク上でカレンダーを共有することができます。iCal ServerはCalDAVという規格に基づいて開発されており、Leopardに付属するiCal 3だけでなくSunbirdやOutlookと連携することもできます。
 なおLeopard Serverに搭載されるカレンダーサーバはオープンソースによる開発がすでに開始されており、次のURLでプロジェクトの内容を参照することができます。

http://trac.macosforge.org/projects/calendarserver

□Wiki Server
 Leopard Serverではチームによる共同作業をサポートする機能が搭載されていますが、Wikiを使って情報の共有を行うことができます。マウス操作によるページの更新や、ページの履歴管理機能が搭載されているようですが、具体的な使い方については製品がリリースされるまで分からないかもしれません。
 また、Wiki Serverではカレンダー、メーリングリスト、ブログとの連携機能も提供されます。

□Spotlight Server
 Tigerで導入されたメタデータ検索のSpotlightが、サーバのサービスとして提供されます。Spotlight Serverでは、クライアントにマウントされたネットワーク上のボリュームの内容を検索することができ、検索のためのインデックス作成はサーバ上で行われます。
 検索時にはアクセス権のチェックも行われ、アクセス権のないファイルが検索結果として表示されないようになっています。

□Podcast Producer
 徐々に普及しつつあるPodcastですが、ビデオの取り込みからエンコーディング、コンテンツ配信までをまとめて行うPodcast Producerが登場します。
 撮影/録音を行ってからコンテンツを公開するまでの処理が自動化されており、クライアント上で収録したデータがLeopard Server上にアップロードされ、Webブラウザ、iTunes、iPod、携帯などに向けて配信することができます。
 エンコーディングは負荷のかかる処理ですが、Xgridを利用することにより複数のマシン上で分散してエンコーディングを実行することも可能です。

□64bit
 サーバアプリケーションの多くが64ビット対応し、処理能力の向上と大量のデータ処理が期待できます。具体的には次のアプリケーションが64ビット対応します。

・64ビット対応サーバアプリケーション
  Apache、MySQL、Postfix、Cyrus、iChat Server
  QuickTime Streaming Server

□その他
 Leopard Serverにはこの他にも様々な新機能が搭載されています。これまで長い間Apache 1.3を使っていたWebサービスはApache 2.2に切り替わり、ディレクトリサーバのOpen Directoryは、クロスドメイン認証、複製のカスケード化、AirMacのためのRADIUS認証に対応しています。

 このように非常に多くの機能がLeopard Serverに新たに搭載されます。新機能を追いかけるだけでも時間がかかりそうですが、実際にLeopard Serverがリリースされましたら、またその詳細をレポートしたと思います。

・Leopard Server先行プレビュー
http://www.apple.com/jp/server/macosx/leopard/

つづく

小池邦人のCarbon API 徒然草(2006/12/22)

〜 Carbonモダンアプリケーションへの道(その8) 〜

前回は、ユニコード文字列を操作するAPIの特徴や利用方法などを取り上げてみました。その中で、Localizable.stringsの活用法を解説しましたが、そのサンプルの返す文字列中に「%1$@」といった変わった表記をみかけました。これは、どんな意味を持つのでしょうか? 今回は、こうした表記の仕組みを解説してみます。

前回のLocalizable.stringsサンプルの一行を再度見てみます。

VersionFormat = "%1$@ (%2$@)";     // for example, "4.0d8 (150)"

横のコメントには”4.0d8 (150)”と記述されていますので、バージョン番号を表記するためのフォーマットであることが分かります。つまり、%1$@には”4.0d8″が、%2$@には”150″が入ることになります。もうお気づきだと思いますが、%1$@や%2$@は、文字列中に別の文字列や数値を挿入するための書式変換フォーマットです。これと同様な仕組みで有名なものは、printf()で用いられる%d(整数の引数用)や%f(浮動小数点の引数用)といった書式変換フォーマットです。

%1や%2が引数の順番を示し、その後の$@がどんな種類の物を挿入するのかを表しています。ちなみに、$@はCore Foundation Frameworkで用いられているオブジェクトを指しており、文字列を参照するCFStringRefなどもこれに相当します。つまり、CFStringRefを渡すことでオリジナル文字列に別の文字列を挿入することなどが可能なのです。こうした書式変換フォーマットを含んだ文字列を自作アプリケーション内で活用するには、前回紹介したFCopyLocalizedString()と、以下のCFStringCreateWithFormat()を同時に用います。

CFStringRef CFStringCreateWithFormatAndArguments (
   CFAllocatorRef  alloc,
   CFDictionaryRef formatOptions,
   CFStringRef     format,          // 書式変換フォーマット付文字列
   va_list         arguments
);

NULLを代入することで1番目のと2番目の引数は省略できます。先んじてCFStringRefとして定義しておいたcfstr2に”4.0d8″が、cfstr3の方には”150″が代入されているとすると、上記サンプル行のバージョン文字列を得るには以下のように記述すればOKです。これで、cfstrに目的のバージョン文字列が返ります。

cfstr1=CFCopyLocalizedString( CFSTR( "VersionFormat" ),"" );
cfstr=CFStringCreateWithFormatAndArguments( NULL,NULL,cfstr1,cfstr2,cfstr3 );

文字列の代わりに整数値などを挿入する場合には、$@の代わりに$dを用います。

PRINT_PAGE="%1$d/%2$d ページ";
PRINT_MONTH="%1$d 月度";

書式変換フォーマットに関する仕様は、ほとんどprintf()と同じであり、詳細についてはApple社が提供しているドキュメント「String Programming Guide for Cocoa」に詳しく載っていますので、そちらを参照してみてください。

「String Programming Guide for Cocoa」

http://developer.apple.com/documentation/Cocoa/Conceptual/Strings/Strings.pdf

続いてサンプルルーチンを幾つか紹介しておきます。最初は、Cストリングスとしてキーワードを渡し、Localizable.stringsに定義されている文字列を得るルーチンです。その次は、CFStringRefをユニコード文字列に変換してから返すルーチンです。以前紹介した自作のcToCFString()やcfToUnicodeString()ルーチンを活用しています。

OSErr getLocalCFString( char *str,CFStringRef *cfstr )
{
    CFStringRef   cfstr1;
    short         err=1;

    *cfstr=NULL;
    if( ! cToCFString( str,&cfstr1 ) ) // キーワード文字列をCFStringRefに
    {
        if( *cfstr=CFCopyLocalizedString( cfstr1,"" ) ) // 文字列の読み込み
            err=noErr;
        disposeCFString( cfstr1 );
    }
    return( err );
}

OSErr getLocalUnicodeString( char *str,HFSUniStr255 *ustr )
{
    CFStringRef   cfstr,cfstr1;
    short         err=1;

    ustr->length=0;
    if( ! cToCFString( str,&cfstr1 ) )  // キーワード文字列をCFStringRefに
    {
        if( cfstr=CFCopyLocalizedString( cfstr1,"" ) ) // 文字列の読み込み
        {
            err=cfToUnicodeString( cfstr,ustr ); // CFStringRefをユニコードに
            disposeCFString( cfstr );   // CFStringRefリリース自作ルーチン
        }
        disposeCFString( cfstr1 );
    }
    return( err );
}


また、文字列中に整数値(変数として)をひとつだけ挿入したい場合があります。以下の例では、1から12のどれかの整数値を挿入して「1 月度」や「12 月度」という文字列を生成したいわけです。

PRINT_MONTH="%1$d 月度";

こんな場合には、CFStringCreateWithFormat()に整数値をひとつだけ渡すルーチンを作成しておけば便利です。

OSErr insertNumberUnicodeString( char *str,long val,HFSUniStr255 *ustr )
{
    CFStringRef   cfstr,cfstr1,cfstr2;
    short         err=1;

    ustr->length=0;
    if( ! cToCFString( str,&cfstr1 ) )        // キーワード文字列をCFStringRefに
    {
        if( cfstr2=CFCopyLocalizedString( cfstr1,"" ) ) // 書式変換文字列を得る
        {
            if( cfstr=CFStringCreateWithFormat( NULL,NULL,cfstr2,val ) )
            {                                 // 引数で渡された整数値を挿入する
                err=cfToUnicodeString( cfstr,ustr );    // CFStringRefをユニコードに
                disposeCFString( cfstr );     // CFStringRefリリース自作ルーチン
            }
            disposeCFString( cfstr2 );
        }
        disposeCFString( cfstr1 );
    }
    return( err );
}


それから、先ほどの例において%1$@と%2$@に代入する文字列もLocalizable.stringsに登録されているとすると…

VersionFormat = "%1$@ (%2$@)";

次のようなルーチンで対応することができます。

OSErr insertTwoCFString( char *str1,char *str2,char *str3,CFStringRef *cfstr )
{
    CFStringRef  cfstr1,cfstr2,cfstr3;
    long         chk1,chk2;
    short        err=1;

    *cfstr=cfstr1=cfstr2=cfstr3=NULL;
    if( ! getLocalCFString( str1,&cfstr1 ) )   // 書式変換用文字列を得る
    {
        chk1=getLocalCFString( str2,&cfstr2 ); // ひとつめ挿入文字列を得る
        chk2=getLocalCFString( str3,&cfstr3 ); // ふたつめ挿入文字列を得る
        if( chk1==noErr && chk2==noErr )
        {
            if( *cfstr=CFStringCreateWithFormat(NULL,NULL,cfstr1,cfstr2,cfstr3))
                err=noErr;                     // ふたつの文字列を挿入
        }
        disposeCFString( cfstr3 );  // CFStringRefリリース自作ルーチン
        disposeCFString( cfstr2 );
        disposeCFString( cfstr1 );
    }
    return( err );
}


次回は、こうして入手した文字列をウィンドウに表示したりプリントアウト(印刷)したりする状況を考えてみます。昔であれば、QuickDraw APIのDrawString()などを用いれば簡単でしたが、モダンアプリケーションではいったい何を使えば最良なのでしょうか?

つづく

SqueakではじめるSmalltalk入門   第76回  鷲見 正人

本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、作成中のGUIビルダをいったん完成させます。

▼ウィジェット削除時の処理の修正
近々ご紹介したいと思っている、先頃リリースされた最新版のSqueak3.9での動作確認をしていたところ、うっかりミスに気付くことができましたのでこの機会に修正させてください。問題はウィジェットをレイアウトからクリックで削除するための#removeWidgetFrom:にありました。

removeWidgetFrom: window
   | clickPoint selected |
   clickPoint := Point fromUser.
   selected := window paneMorphs
      detect: [:morph | morph bounds containsPoint: clickPoint]
      ifNone: [].
   selected
      ifNotNil: [selected delete]


最後のdeleteだけでは不十分で、削除した結果をpaneMorphsに反映させるための#updatePanesFromSubmorphsをコールする必要があります。ウィジェット削除後、見えない枠変更用UIの亡霊たちに悩まされたかた、ごめんなさい(3.9ではこのUIが実体を持つように変更されたため、気が付きました…汗)。#paneMorphSatisfying:という便利メソッドも活用して次のように書き換えることにいたしましょう。

removeWidgetFrom: window
   | clickPoint selected |
   clickPoint := Point fromUser.
   selected := window
      paneMorphSatisfying: [:morph | morph bounds containsPoint: clickPoint].
   selected ifNotNil: [
      selected delete.
      window updatePanesFromSubmorphs]

▼ウインドウを生成するためのコード出力
仕上げには、GUIビルダ上でデザインしたGUIをコードとして出力するメニュー項目を設置します。必要な作業は二つ。ひとつは、もうお馴染みの、#addModelItemsToWindowMenu:の最後に該当記述を追加すること。メニュー項目名は「show script」、起動するメソッドは「#generateScriptOf:」としました。

addModelItemsToWindowMenu: aMenu
   window := aMenu defaultTarget.
   aMenu addLine.
   (self class allMethodsInCategory: 'widget types') do: [:widgetSym |
      aMenu
         add: 'add ', widgetSym
         target: self
         selector: #add:to:
         argumentList: {widgetSym. window}].
   aMenu addLine.
   aMenu add: 'delete' target: self selector: #removeWidgetFrom: argument: window.
   aMenu addLine.
   aMenu add: 'show script' target: self selector: #generateScriptOf: argument: window

必要なことのもうひとつは、呼び出される側の#generateScriptOf:を定義する

generateScriptOf: window
   | sourceCodes method widgetClass sourceCode file start frame |
   sourceCodes := Dictionary new.
   (self class allMethodsInCategory: 'widget types') do: [:selector |
      method := self class compiledMethodAt: selector.
      widgetClass := method literals
         detect: [:lit | lit asString beginsWith: '#Pluggable'].
      sourceCode := method getSourceFromFile asString.
      start := sourceCode indexOf: $^.
      sourceCode := sourceCode allButFirst: start + 1.
      sourceCodes at: widgetClass value put: sourceCode].
   file := FileStream newFileNamed: 'mywindow.st'.
   [  file nextPutAll: '| model window |'; cr.
      file nextPutAll: 'model := Model new.'; cr.
      file nextPutAll: 'window := '.
      file nextPutAll: '(SystemWindow labelled: ''My Window'') model: model.'; cr.
      window paneMorphs do: [:morph |
         file nextPutAll: 'window addMorph: ('.
         file nextPutAll: (sourceCodes at: morph class).
         file nextPutAll: ') frame: ('.
         frame := morph layoutFrame.
         file nextPutAll: (
            frame leftFraction @ frame topFraction
               corner: frame rightFraction @ frame bottomFraction) printString.
         file nextPutAll: ').'; cr].
      file nextPutAll: '^ window openInWorld']
   ensure: [file ifNotNilDo: [:f | f edit]]

少し長めなうえ、Smalltalkならではの機能を多用(乱用?)しているので、細かな解説は次回以降としますが、大枠ではこんなことをしています。

1. ‘widget types’に分類してあるメソッドのソースをカタログ化。
2. 各ウィジェットからレイアウト情報を引き出す。
3. ソースとレイアウト情報を組み合わせて加工し、スクリプトを構成。
4. スクリプトをmywindow.stファイルに出力後、あらためてそれを表示。

正月休みをはさんで次回まですこし間があくので、これまでの復習を兼ねて、#generateScriptOf:の読み解きにチャレンジしてみてはいかがでしょうか。ちなみに、「show script」で現われたウインドウ内のコードを選択してdo it(cmd + D)すると、完成品のウインドウが得られます。スクリプトを変更して、適切なモデルと正しく接続すれば、アプリのGUIとして機能するようになります。こちらの解説もいずれ。

それでは、よいお年をお迎えください。

バックナンバー:

ニュース・解説

 今週の解説担当:木下 誠

———————————————————————-
3Dアプリケーション「modo」開発者インタビュー
———————————————————————-

「modo」という3Dグラフィックアプリケーションを開発している、Luxologyの開発者インタビューである、「Making modo a Great Mac App: Luxology Uses Tools, Quartz and OpenGL」が公開されています。

Mac OS Xの強みとして、QuartzやOpenGLといったグラフィックフレームワークがあること、XcodeやSharkといった強力な開発ツールがあること、を挙げています。

Making modo a Great Mac App: Luxology Uses Tools, Quartz and OpenGL
http://developer.apple.com/business/macmarket/modo.html

———————————————————————-
カスタムファイルシステムの、ボリュームをマウントする
———————————————————————-

最近何度か登場している、カスタムのファイルシステムを作成する話題です。自分で作成したファイルシステムのボリュームを、デスクトップにマウントする方法を解説した、「QA1491: Volumes Not Showing Up On The Desktop」が公開されています。

ファイルシステムのマウントには、適切なファイルシステムバンドルを作成する必要があります。このバンドルは、/System/Library/Filesystemsにインストールします。

また、DiskArbitrationフレームワークを使って、ノーティフィケーションを送る必要があります。

QA1491: Volumes Not Showing Up On The Desktop
http://developer.apple.com/qa/qa2006/qa1491.html

———————————————————————-
言語環境での並び順を取得する
———————————————————————-

Mac OS Xはローカライズのシステムが非常に優れており、環境設定パネルの言語環境で使用する言語の優先順位を指定しておけば、それに対応するリソースをシステムが自動的に選択してくれます。

でも、それとは別に、ここで指定されている言語の優先順位を調べたいときもあるでしょう。その方法を解説した、「QA1391: How can I determine the order of the languages set by the user in the Language tab of the Internation preference pane?」が公開されています。

この順位は、ユーザデフォルトから取得することができます。Cocoaならば、NSUserDefaultsを使って、”AppleLanguages”というキーの値を調べます。Carbonならば、CFPreferencesを使います。

QA1391: How can I determine the order of the languages set by the user
in the Language tab of the Internation preference pane?
http://developer.apple.com/qa/qa2006/qa1391.html

———————————————————————-
Carbonアプリのスケルトン
———————————————————————-

Carbonアプリケーションを作るときのスケルトンとなるサンプル、「DTSCarbonShell」が公開されています。

DTSCarbonShell
http://developer.apple.com/samplecode/DTSCarbonShell/index.html

 

◇MOSAからのお知らせと編集後記は割愛します◇

 

MOSA Developer News   略称[MOSADeN=モサ伝]
      記事投稿受付 http://www.mosa.gr.jp/topics/mdn-toukou.html
Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2006 MOSA. All rights reserved.