HMDT - Logic and Intuition -

about HMDT

Cocoa Programming Tips 1001

Foundation

NSDictionary

Foundation - NSDictionary

プロパティリスト表示を取り出す、その逆も

Keywords: description

NSDictionary を、プロパティリスト形式でフォーマットされた文字列に変換することができるんだ。ファイルに保存するときなんかに便利なんだ。とうぜん、その逆、つまり文字列から NSDictionary に戻すこともできる。

変換するには description メソッドを使うんだ。

Foundation/NSDictionary.h

- (NSString*)description;

これを使うと、key や value として入っている、NSString、NSArray、NSDictionary、NSData を変換できるんだ。早速テストしてみよう。

(sample)

    NSMutableDictionary* dict;
    dict = [NSMutableDictionary dictionary];
    char data[] = {0, 1, 2, 3, 4, 5, 6, 7};
    
    [dict setObject:@"Music list" 
          forKey:@"NSString"];
    [dict setObject:
              [NSArray arrayWithObjects:
                  @"As Praaias Desertas", 
                  @"Amor Em Paz", 
                  nil] 
          forKey:@"NSArray"];
    [dict setObject:
              [NSDictionary dictionaryWithObject:
                  @"value" 
                  forKey:@"key"] 
          forKey:@"NSDictionary"];
    [dict setObject:[NSData dataWithBytes:data length:8] 
          forKey:@"NSData"];
    
    NSLog("%s¥n", [dict description]);

結果はこんな感じ。

(result)

{
    NSArray = ("As Praaias Desertas", "Amor Em Paz"); 
    NSData = <00010203 04050607 >; 
    NSDictionary = {key = value; }; 
    NSString = "Music list"; 
}

結果から分かるように、

  • NSArray は (item0, item1)
  • NSDictionary は { key = value; }
  • NSData は <01234567 89ABCDEF >

っていうフォーマットに入れられてくるんだ。このままファイルに保存してやればいい。

逆にこのフォーマットから NSDictionary を作るには、NSString の propertyList メソッドを使うんだ。

Foundation/NSString.h

- (id)propertyList;

これを使えば、元に戻るぜ。

Foundation - NSDictionary

プロパティリストを XML 形式で取り出す

Keywords: Property list service

上の例では、プロパティリストを description の形式で取り出したけど、Mac OS X では XML 形式のプロパティリストもサポートしているんだ。たとえば、アプリケーションラッパーの中の、Info.plist とかで使われているでしょ。

その XML 形式を作るにはどうしたらいいか?Cocoa-Java を使っているならば、NSPropertyListSerialization の XMLDataFromPropertyList() が使える。

NSPropertyListSerialization.java

public static NSData XMLDataFromPropertyList(
        Object propertyList);

じゃ、Objective-C の場合は?Cocoa の中には API が見当たらない。だけど CoreFoundation の Property lsit service を使うことができるんだ。Property list service の中の CFPropertyListCreateXMLData() を使えばいい。

CoreFoundation/CFPropertyList.h

CFPropertyListRef CFDataRef CFPropertyListCreateXMLData(
    CFAllocateorRef allocator, 
    CFPropertyListRef propertyList);

CFPropertyListRef には NSDictionary や NSArray とかを指定できるんだ。適当なインスタンスを指定して呼んでやれば、CFDateRef (NSData) 型で XML 表現が返ってくる。

これを使って、NSDictionary を拡張してみよう。カテゴリを使って新しいメソッドを付け加える。xmlDescription って名前を付ける。

NSDictionary_Extension.h (sample)

@interface NSDictionary (XMLDescription)

- (NSString*)xmlDescription;

@end

実装はこんな感じ。

NSDictionary_Extension.h (sample)

@implementation NSDictionary (XMLDescription)

- (NSString*)xmlDescription
{
    NSData*	xmlData;
    
    xmlData = (NSData*)CFPropertyListCreateXMLData(
            kCFAllocatorSystemDefault, 
            (CFPropertyListRef)self);
    
    return [[NSString alloc] 
            initWithData:xmlData 
            encoding:NSUTF8StringEncoding];
}

@end

じゃ、早速テストをしてみる。テストプログラムの中で適当な NSDictionary を作って description 形式と XML 形式を表示させてみた。

(result)

NSDictionary description:

{
    ArrayItem = ("Power Book", iBook); 
    BoolItem = 1; 
    FloatItem = 1; 
    IntItem = 128; 
    StringItem = Macintosh; 
}


XML format:

<?xml version="1.0" encoding="UTF-8"?>
<plist version="0.9">
<dict>
	<key>ArrayItem</key>
	<array>
		<string>Power Book</string>
		<string>iBook</string>
	</array>
	<key>BoolItem</key>
	<true/>
	<key>FloatItem</key>
	<real>1.000000e+00</real>
	<key>IntItem</key>
	<integer>128</integer>
	<key>StringItem</key>
	<string>Macintosh</string>
</dict>
</plist>

こんな感じ。注意してほしいのは数字の値の取り扱い。ここでは BOOL 型、int 型、float 型の数字を渡してみた。description 形式では、BOOL の YES が 1 になり、float の 1.0 も 1 になって、型情報が失われているよね。でも XML 形式では、BOOL の YES は <true/> になって、float の 1.0 は <real>1.000000e+00</real> になっている。数字型の型情報がきちんと含まれているのが利点だね。

■サンプルダウンロード:
XMLPlist.tar.gz

back to top content

Copyright © 2002-2006 HMDT. All rights reserved.