MOSA Multi-OS Software Artists

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

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

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

2005-03-01

目次

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

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

 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。

 「コレクション」と呼ばれるオブジェクトは、Collectionとそのサブクラス群によって定義され、文字通り、要素の集まりを表現するために使います。どのようなルールで要素を集めて扱うか、あるいは、どんな要素を対象にするのかといった目的別に使い分けます。Smalltalkのコレクションは非常に数が多く、その多さに初心者は(特に他の言語に精通している人ほど)面食らってしまうようです。どのくらい多いか、その数を知ることは簡単にできます。

Collection allSubclasses size ” => 88 ”

 Smalltalkシステムが返してきたこの答えを信じるならば、なんと90個近いコレクションがあることになるわけです。もっとも「これをすべて覚えなければならないのか…」とのご心配にはおよびません。そのほとんどは特殊な用途向けに用意されたもので、普段から覚えておく必要があるのはほんのいくつかにすぎないからです。

 Smalltalkシステム、つまり暫定ダイナブック環境においては、他のOSに比べて、あらゆる情報がすべてオープンで、しかも異常なほど容易にアクセスできるため、つい、ひとつひとつ実際に手にとって確かめたくなってしまいがちです。そうした姿勢自体は悪いことではないですし、それ、つまりエンドユーザーが自身の使用しているシステムのしくみを知りたくなるよう仕向けることは、まさにアラン・ケイの狙いでもあるわけですが、初心のうちはほどほどにしておかないと、情報の多さに押しつぶされてしまいます。うまく捨て目を利かせつつ、適度に無視するのが、Smalltalkとうまくつき合うためのコツだと言えそうです。

 さて。普段から覚えておいたほうがよいいくつかのコレクションというのは、なにも特別なものではなく、Cocoaに用意されているコレクションとほぼ一致します。これはけっして偶然というわけではありません。なぜなら、Cocoaの前身であるNEXTSTEP(のAPI)は、Smalltalkの雑然としたクラス群をライブラリとして使いやすく整理・再構築したものだとも言えるので、むしろ当然のことでしょう。

 SmalltalkのコレクションとCocoaのコレクションの対応は、おおよそ次の通りです。

NSArray …… Array
NSMutableArray …… OrderedCollection
NSDictionary …… Dictionary
NSSet …… Set
NSCountedSet …… Bag
NSString …… Symbol
NSMutableString …… String

 念のため、それぞれがどんな特徴を持っているかについても簡単に紹介しておきます。

 Arrayはすでにご存じでお馴染みの「配列」です。各要素は前後関係を保持しつつ管理され各々にインデックスが振られます。ただ、Cocoaとは異なりSmalltalkではインデックスは0からではなく1から始まり、最後の要素のインデックスは全要素数に一致します。また、NSArrayと違ってArrayでは、要素を変更することができますが、要素数の増減は(NSArray同様)できません。要素数を増減させる用途には、Arrayではなく、OrderedCollectionを使います。

 Dictionary、Set、Bagは、要素の順番を考慮しないコレクションです。Dictionaryは名前のとおり「辞書」です。「キー(key)」に「値(value)」を対応付けて要素として管理してくれます。Setは要素の重複を許しません。すでに存在する要素を追加しようとしても無視されます。Setの「要素の重複を許さない」という制約を取り払ったのがBagです。

 SymbolとStringは、Array同様、これまでも何度か登場していますね。Symbolには、NSMutableStringに対しNSStringの持っているImutableであるという性質の他に、同値なら同一オブジェクトであることを保証する(つまり、同内容のコピーの存在を許さない)という特性も備わっています。「= arg」はレシーバとargが同値かどうかを、「== arg」は同一かどうかをテストしたいときに送るメッセージです。

#symbol = #symbol copy ” => true ”
#symbol == #symbol copy ” => true ”
‘string’ = ‘string’ copy ” => true ”
‘string’ == ‘string’ copy ” => false ”

 シンボル、文字列に関しては、大島芳樹さんら日本人Squeakユーザーの有志により構築された多国語対応版を用いることで、いわゆるマルチバイト文字列への対応も可能です。多国語版Squeakをベースにした日本語版は、次のサイトより入手できます。日本語版については、現在最新版の開発が最終段階に入っているようなので、近いうちにご紹介できると思います。

http://squeak.hp.infoseek.co.jp/nihongo.htm

 以上の他に、範囲や等差数列を表わすのに用いるInterval、常に要素がソートされた状態で保たれるSortedCollectionを知っておけば、当面、コレクション関係で不自由はしないはずです。

バックナンバー:
http://squab.no-ip.com:8080/mosaren/

小池邦人の「Carbon API 徒然草」(2005/02/25)

Navigation Service APIの活用(その5)

今回は、navMyGetFile()から呼ばれているnavGetImportTypeList()とnavMakeTypeList()の2つの自作ルーチンを解説することで、ファイル選択時の「ファイルタイプ」と「拡張子」の混在問題について考えてみます。

特殊なアプリケーション(例えばファイルメンテナンスやユーティリティ関連など)を除き、一般的なアプリケーションでは、ユーザが選択すべきファイルの種類は限定されています。選択しても意味の無いファイルは、ファイル選択ダイアログのブラウザで選択不可(グレイ表示)にしておくのが、Macintoshユーザインターフェースにおける一般的なルールです。具体的には、選択対象であるファイルタイプの配列(NavTypeList構造体)をNavTypeListHandleへ格納してから、NavGetFile()へ引数として渡してやります。アプリケーション自身で作成されたドキュメントをオープンする場合には、通常そのファイルタイプはひとつで固定されていますので、NavTypeListを作成することは至極簡単な作業となります。しかし、場合によっては、渡すべきNavTypeListの内容やその総数を確定できない場合もあります。

その代表的な例が、様々な画像ファイルをオープンするために「QuickTime Importer」を使う場合です。QuickTimeがバージョンアップする度に、Importerでオープン可能な画像ファイルの種類は増加していきました。つまり、インストールされているQuickTimeのバージョンにより、対応ファイルの種類の総数が異なるわけです。まあ、「オープンするファイルはPICT、TIFF、JPEG、8BPS(Photoshop)だけに固定だ!」と決めつけてしまえば、その4タイプをNavTypeListに代入するだけで済むので話は簡単です。しかし、それではせっかくのImporterの強力な能力を制限してしまうことになります。それを避けるのためには、現バージョンのQuickTime Importerでオープンできるファイルタイプの種類と総数を、リアルタイムで把握する必要があるわけです。

以下が、QuickTime Importerによりオープン可能なファイルタイプの種類と総数を返すnavGetImportTypeList()ルーチンです。仕組みは簡単でして、Importerが取り扱い可能な画像ファイルは、それを処理するためのコンポーネント(システムモジュール)に一対一で対応していますので、それを順次読み出して、そこからファイル情報を得るわけです。

void navGetImportTypeList( OSType type[],short *nb )
{
    ComponentDescription    looking;
    Component               cc=0;
    short                   ct=0;
    ComponentDescription    cd;

    looking.componentType=GraphicsImporterComponentType; // 対象コンポーネントに
    looking.componentSubType=0;                          // GraphicsImporterを指定
    looking.componentManufacturer=0;
    looking.componentFlags=hasMovieImportMIMEList;
    looking.componentFlagsMask=movieImportSubTypeIsFileExtension|
                                                    hasMovieImportMIMEList;
    while( cc=FindNextComponent( cc,&looking ) )   // コンポーネントを順次得る
    {
        GetComponentInfo( cc,&cd,NULL,NULL,NULL ); // コンポーネントの情報を得る
        type[ct++]=cd.componentSubType;            // OSTypeの配列に代入する
    }
    *nb=ct;                                        // コンポーネント数を返す
}


何らかの操作(例えばDrag&Drop)で得られたファイルタイプが、Importerでオープン可能な種類かどうかを判断するには、以下のような簡単なルーチンを用意すればOKです。

short navImportCheckTypeList( OSType type )
{
    OSType   type1[1000];
    short    i,ct;

    navGetImportTypeList( type1,&ct );
    for( i=0;i<ct;i++ )
    {
        if( type==type1[i] )
            return( noErr );
    }
    return( 1 );
}


おまけとして、「QuickTime Exporter」で取り扱い可能な画像ファイルタイプの一覧を得るためのnavGetExportTypeList()ルーチンを紹介しておきます。
QuickTime Exporterは、メモリ(CGrafPortやGWorldなど)上に展開した画像データを、指定タイプの画像ファイルとして保存する場合に活用します。

void navGetExportTypeList( OSType type[],short *nb )
{
    ComponentDescription    looking;
    Component               cc=0;
    long                    ct=0;
    ComponentDescription    cd;

    looking.componentType=GraphicsExporterComponentType; // 対象コンポーネントに
    looking.componentSubType=0;                        // GraphicsExporterを指定
    looking.componentManufacturer=0;
    looking.componentFlags=0;
    looking.componentFlagsMask=0;
    while( cc=FindNextComponent( cc,&looking ) )   // コンポーネントを順次得る
    {
        GetComponentInfo( cc,&cd,NULL,NULL,NULL ); // コンポーネントの情報を得る
        type[ct++]=cd.componentSubType;            // OSTypeの配列に代入する
    }
    *nb=ct;                                        // コンポーネント数を返す
}


こうして得られたOSTypeの配列を、NavTypeListHandleへ保存するのがnavMakeTypeList()ルーチンです。与えられたファイルタイプの総数から必要とされるメモリ容量を計算し、NewHandleClear()でHandleを確保した後に、ファイルタイプをひとつずつ代入します。ちなみに、NavTypeList構造体はヘッダーファイルのNavigation.hに以下のように定義されています。
NavTypeListHandleを確保する場合には、OSTypeの配列箇所が総数分増えるとみなし、その容量を計算するわけです。

struct NavTypeList {

    OSType   componentSignature;
    short    reserved;
    short    osTypeCount;
    OSType   osType[1];

    };

short navMakeTypeList( short ct,OSType type[],NavTypeListHandle *list )
{
    short               i,ret=1;
    long                size;
    NavTypeListHandle   lhd;

    size=sizeof(NavTypeList)+sizeof(OSType)*(ct-1);      // Handleのサイズ計算
    if( lhd=(NavTypeListHandle)NewHandleClear( size ) )  // Handleを確保する
    {
        (*lhd)->osTypeCount=ct;             // ファイルタイプの総数を代入
        (*lhd)->componentSignature=MY_SIG;
        for( i=0;iosType[i]=type[i];      // 個々のファイルタイプの代入
        ret=noErr
    }
    *list=lhd;
    return( ret );
}


ここで注意する点は、上記のような操作で得られたNavTypeListHandleをNavGetFile()に渡したとしても、「拡張子」でしかその種類を判断できないファイルには選択表示処理が適応されないということです。本当ならば、「’JPEG’ファイルタイプは表示する!」と設定しさえすれば、Navigation Service側で対応データベースを参照し、ファイルタイプが付加されていないファイルであっても、拡張子が’.jpg’や’.jpeg’のファイルは選択対象だと「賢く判断」してくれるのが人の道でしょう(せめてImporterやExporterが対応しているファイルぐらいは…)。残念ながら、現状のNavigation Serviceはそれほど賢くないため、開発者側で面倒な前処理や後処理を追加する手間が発生してしまいます。

次回は,今回説明できなかったもうひとつの自作ルーチンnavCheckImportExtention()を紹介し、それをNavGetFile()のフィルター内で使うケースを解説します。また、拡張子もファイルタイプもない画像に遭遇した時、そのファイルがオープン可能かどうかを判断するための簡単な手段も紹介したいと思います。

「Behind the WebObjects」  第38回  田畑 英和

 これまで運用環境について連載で取り上げたことはありましたが、運用をおこなうための実際の手順はまだ解説していませんでしたので、今回は運用手順に注目してみたいと思います。またたんに操作方法を解説するだけではなくなるべくその背景部分についても説明していくことにします。

インストール

 運用をおこなうには開発をおこなったアプリケーションのインストールをおこなわなければなりません。ここではMac OS XとXcodeを対象に、コマンドライン上でのインストール方法について解説します。
 Xcodeがインストールされた開発環境には、”xcodebuild”というビルドを実行するコマンドが用意されています。このコマンドを用いてXcodeプロジェクトのビルドをおこなえますので、WebObjectsでもこのコマンドを利用することができます。インストールをおこなうには「ターミナル」を起動してプロジェクトが存在するディレクトリに移動し、以下の2つのコマンドを実行してください。なお以下の操作は開発環境上でおこなうものとし、まずは開発環境上でインストールをおこなってから、後で運用環境に転送することとします。

・インストールコマンド
sudo xcodebuild install DSTROOT=/ -buildstyle Deployment
sudo xcodebuild install DSTROOT=/ -buildstyle WebServer

・インストールが成功した場合のメッセージ
** BUILD SUCCEEDED **

 sudoコマンド経由での利用となりますので、実行時にはパスワードの入力が求められ、パスワード認証後にビルドが実行されます。インストールが成功しますと上記のメッセージが表示されますが、インストールが確実に成功するように、まずはXcode上でプロジェクトをクリーニングしてからビルドができることを確認しておくのがよいでしょう。
 インストールが成功しますと以下のパスにそれぞれ拡張子”.woa”をもったアプリケーションが作成されます。

・デフォルトのインストール先
/Library/WebObjects/Applications
/Library/WebServer/Documents/WebObjects

 アプリケーション本体は1つ目のパスにインストールされ、プロジェクト内のWeb Server Resources(正確にはターゲットがWeb Serverのファイル)が2つ目のパスにインストールされます。インストール時にはxcodebuildコマンドを2回実行する必要がありますが、2回目の実行はWeb Server Resourcesをインストールするためです。
 このようにWebObjectsではアプリケーションを2カ所に分けてインストールし、Javaのクラスファイルなどのアプリケーション本体はWebサーバの領域外に配置し、GIF/JPEGファイルなどのリソースファイルはWebサーバの領域内に配置します。

インストール先の設定

 インストール先はプロジェクトのターゲット設定で変更することができます。プロジェクトをXcodeで開き、左側の「グループとファイル」からプロジェクト名と同じ名前のターゲットを選択します。すると右側にターゲットの設定項目が表示されますので、「設定」->「シンプルビュー」->「インストール先」を選択するとインストール先を変更することができます。

・デフォルトのインストール先
$(LOCAL_LIBRARY_DIR)/WebObjects/Applications

開発環境から運用環境へ

 通常は開発環境とは別に運用環境用のサーバを用意し、そちらでアプリケーションを稼働させることになりますが、そのためには開発環境上でインストールしたアプリケーションを運用環境に転送する必要があります。
 2カ所にインストールされたアプリケーションをそれぞれ運用環境に転送すればよいのですが、開発環境とは異なったOSで運用をすることも考えられますので、環境にあった方法で転送をおこなってください。例えばApple Remote Desktopを使用して運用環境へアプリケーション一式をコピーすることもできます。なお運用環境へのファイル転送の際には各ファイルのパーミッションなどに注意してください。転送後には運用環境のコマンドライン上でアプリケーションの起動を確認するとよいでしょう。

 開発環境上では正しく動作していたアプリケーションも、運用環境ではうまく動作しない場合もあります。こういった場合にはいくつかの原因が考えられますが、まずはフレームワークやJDBCドライバなどアプリケーション以外に必要なファイルが正しくインストールされているかを確認してください。
 またモデルファイルの接続情報が間違っている場合も考えられます。運用環境上ではEOModelerがインストールされていないとGUI上で接続情報を確認することができませんが、モデルファイルはテキストエディタで直接設定を確認することもできます。モデルファイルはファイルシステム上では実際にはディレクトリですが、モデルファイルのディレクトリ内にある”index.eomodeld”を調べることでJDBCのURLなどの接続情報を確認することができます。

・モデルファイル内のJDBCの接続情報
URL = “jdbc:openbase://127.0.0.1/WOMovies”;

 さて、今回は運用のための手順としてインストール方法を紹介しました。もちろん実際にアプリケーションを運用するためにはあらかじめWebObjectsの運用環境が正しくセットアップされている必要がありますし、インストール後にも様々な設定が必要になってきます。それでは次回も今回に引き続き運用手順について解説してみたいと思います。

ニュース・解説

今週の解説担当:木下 誠

———————————————————————-
Apple Remote Desktop 2 のデータベースにアクセスする方法
———————————————————————-

Appleが、Apple Remote Desktop 2 が管理するデータベースにコマンドラインでアクセスする方法や、アプリケーションを作成してアクセスする方法を解説した、「Providing Application Access to SQL Data in Apple Remote Desktop 2」というドキュメントを公開していました。

Apple Remote Desktop 2 では、クライアントコンピュータの情報を管理するために、PostgreSQLを利用しています。このデータベースに格納されている情報は、Apple Remote Desktop 2に含まれている管理アプリケーションで参照することができますが、一般的なSQLを使ってアクセスすることもできます。このドキュメントでは、SQLアクセスを可能にするためのPostgreSQLの設定の変更、およびpsqlコマンドを使ったデータベースへのアクセス方法を紹介しています。

また、管理専用アプリケーションを作る例として、REALBasicを使ったデータベースへの接続を紹介しています。REALBasicはPostgreSQLへアクセスするためのデータベース・プラグインを含んでいるため、簡単に利用することができます。
Apple Remote Descktop 2を使って管理をしている方、またはPostgreSQLでデータベースを構築し管理アプリケーションを作ろうと思っている方に、参考になる記事でした。

Providing Application Access to SQL Data in Apple Remote Desktop 2
http://developer.apple.com/appleapplications/ardsql.html

———————————————————————-
JavaアプリケーションからHelp Viewerを呼び出すサンプル
———————————————————————-

JavaアプリケーションからApple Help Viewerを動作させるサンプル、「HelpHook」が公開されています。実際は、JNIを使って、JavaアプリケーションからCのフック関数を経由し、Cocoa APIを呼び出すサンプルになっています。

Sample Code:
HelpHook
http://developer.apple.com/samplecode/HelpHook/HelpHook.html

———————————————————————-
Sequence Grabberを使ってビデオをキャプチャするサンプル
———————————————————————-

Sequence Grabberを使ってビデオをキャプチャするサンプル、「BrideOfMungGrab」が公開されています。このサンプルは、SGDataProcSampleをベースにした一連のサンプル、Minimung、MungGrab、SonOfMungGrab、の最新作だそうです。

今回は、ビデオの上に文字を書いているのですが、GWorldの使用をやめてCoreGraphicsを使っているそうです。

Sample Code:
BrideOfMungGrab
http://developer.apple.com/samplecode/BrideOfMungGrab/BrideOfMungGrab.html

———————————————————————-
Sequence Grabberでキャプチャするときのファイルサイズ
———————————————————————-

もう1つ、Sequence Grabber関係があります。Sequence Grabberを利用してビデオをキャプチャする際に、QuickTimeはあらかじめ巨大なファイルを確保します。これを避ける方法を説明したTechnical Q&A、「Sequence Grabber preallocates large file when recording」が公開されています。

SGSetOutputMaximumOffsetを使うことで、出力されるデータのサイズを制御することができます。他にも、データを格納する際に有用なAPIが紹介されています。

Technical Q&A QA1411:
Sequence Grabber preallocates large file when recording
http://developer.apple.com/qa/qa2005/qa1411.html

———————————————————————-
QuickTimeのNativePathNameToFSSpecの問題
———————————————————————-

QuickTimeのNativePathNameToFSSpecを呼んだときに、bdNameErrが返る問題を解説したTechnical Q&A、「NativePathNameToFSSpec returns bdNameErr (-37) error」が公開されています。

現在のバージョンのQuickTimeでは、ファイル名+拡張子が63文字を超えるファイルは取り扱えないそうです。いささか、恥ずかしい問題だと思います。

Technical Q&A QA1413:
NativePathNameToFSSpec returns bdNameErr (-37) error
http://developer.apple.com/qa/qa2005/qa1413.html

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

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