NSDictionary

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