Cocoaでいこう! Macらしく 第17回
Yoshiki(DreamField)
この記事は、MOSAが発行するデベロッパ向けのデジタルマガジンMOSADeN 第77号(2003年8月12日発行)に掲載された記事です。2〜3ヶ月遅れで、ここに掲載して行きます。

今週末、年に2回のお祭り夏の部が開催されます。来られる方は、ビックサイトでお会いしましょう(^^;)(ほとんどの方は何のことか分からないと思いますが)。

複数の画像フォーマットを開けるようにしよう

現在のTinyViewは、JPEGファイルしか扱えません。これではちょっと物足りないですね。そこで今回はPICTファイルも扱えるようにしましょう。Mac OS Xになって標準フォーマットでは無くなってしまったとはいえ、やはりMacのアプリだったら、PICTファイルを開けるのは基本でしょう。

PICTを開けるようにするのは簡単です。まずは、JPEGの時にやったように、書類のタイプにPICTを追加します。ターゲットから書類のタイプを選んで、一覧の下にあるプラスボタンを押して下さい(fig.01)。

プラスボタンで一行増やす
[fig.01] プラスボタンで一行増やす

一行増えますので、それを選んで各項目に、次の表の値を入力していって下さい(fig.02)。

名前 PICT
役割 Viewer
拡張子 pct PCT pict PICT
OSタイプ PICT
書類のクラス MyDocument
書類のタイプにPICTを設定する
[fig.02] 書類のタイプにPICTを設定する

現在TinyViewに実装されているプログラムで、実はPICTも開けますので、これだけでPICTが開けるようになったはずです。ビルドして実行し、適当なPICTファイルを開いてみましょう。

さて、開く方はそのままで出来るようになりましたが、保存する方は一つ問題があります。それは、決め打ちでタイプをJPEGにしてしまっていることです。PICTファイルを保存する時は、タイプをPICTにしないといけません。では、これを実装して行きましょう。MyDocument.mを開いて、fileAttributesToWriteToFile:ofType:saveOperation:を見て下さい。このメソッドの引数に、documentTypeNameというのがありますが、ここには書類のタイプで指定した名前が入って来ます。そこで、これを見て、JPEGで保存するのか、PICTで保存するのかを判断して、それぞれに合ったタイプを付加するように改造しましょう。

決め打ちでJPEGというタイプを付加している次の2行を、見つけて下さい。

theType = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'JPEG'")];
[ theMutableDictionary setObject:theType forKey:NSFileHFSTypeCode];

これを以下のコードに置き換えて下さい。

theType = nil;
if( [ documentTypeName isEqualToString:@"JPEG"]){
    theType = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'JPEG'")];
}else if( [ documentTypeName isEqualToString:@"PICT"]){
    theType = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'PICT'")];
}
if( theType){
    [ theMutableDictionary setObject:theType forKey:NSFileHFSTypeCode];
}

一行ずつ見て行きましょう。

tyeType = nil;

theTypeはタイプを表すNSNumberクラスのインスタンスのアドレスを格納するための変数です。まだ何になるのか決定していないので、nilを入れておきます。

if( [ documentTypeName isEqualToString:@"JPEG"]){

documentTypeNameは、NSStringクラスのインスタンスです。リファレンスで調べれば分かりますが、isEqualToString:は、指定されたNSStringクラスのインスタンスと自分が等しいのか比較し、結果を返すメソッドです。つまり、この行で渡って来たdocumentTypeNameが@"JPEG"であるかどうかを見ています。

theType = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'JPEG'")];

そして、@"JPEG"であった時は、この行でtheTypeに'JPEG'をセットしています。この後の2行は同様で、documentTypeNameが@"PICT"の時は、theTypeに'PICT'をセットします。

if( theType){
    [ theMutableDictionary setObject:theType forKey:NSFileHFSTypeCode];
}

そして、theTypeに値がセットされている時のみ、theMutableDictionaryにタイプをセットしています。これで保存も正しく出来るようになりました。ビルドして試してみて下さい。なお、念のために、以下に改造後のfileAttributesToWriteToFile:ofType:saveOperation:の全てを記述しておきます。

- (NSDictionary *)fileAttributesToWriteToFile:(NSString *)fullDocumentPath
                                       ofType:(NSString *)documentTypeName
                                saveOperation:(NSSaveOperationType)saveOperationType
{
    NSDictionary *theDictionary;
    NSMutableDictionary *theMutableDictionary;
    NSNumber *theCreator;
    NSNumber *theType;

    theDictionary = [ super fileAttributesToWriteToFile:fullDocumentPath
                                                 ofType:documentTypeName
                                          saveOperation:saveOperationType];
    theMutableDictionary = [ NSMutableDictionary dictionaryWithDictionary:theDictionary];
    theCreator = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'TNVW'")];
    [ theMutableDictionary setObject:theCreator forKey:NSFileHFSCreatorCode];
    theType = nil;
    if( [ documentTypeName isEqualToString:@"JPEG"]){
        theType = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'JPEG'")];
    }else if( [ documentTypeName isEqualToString:@"PICT"]){
        theType = [ NSNumber numberWithUnsignedLong:NSHFSTypeCodeFromFileType( @"'PICT'")];
    }
    if( theType){
        [ theMutableDictionary setObject:theType forKey:NSFileHFSTypeCode];
    }
    return theMutableDictionary;
}

前回も言いましたが、本来ならタイプはinfo.plistから取得すべきでしょう。今回は、学習用として分かりやすいように、そこは手を抜いています。

ところで、普通、この様なアプリはどのような動作になるでしょうか。良くあるMacのアプリでは、開いた画像のフォーマットに関係無く、保存する時にファイルフォーマットは選べるはずです。ところが現在のTinyViewでは、JPEGを開いた時はJPEGでしか保存できませんし、PICTを開いた時はPICTでしか保存できません。これではMacのアプリとしてあんまりです。そこで次回は、この辺りを改善して行くことにします。

前頁目次次頁