Objective-C から XML へのコンバーター
Objective-C のインターフェースやオブジェクトを貼り付けてください。クリーンな XML が返ってきます。
このツールでできること
古い SOAP サービス、plist ファイル、Cocoa の設定、テストフィクスチャーなど、Objective-C のモデルに合わせた XML ペイロードを手で組み立てたことがあるなら、あの手間はよくわかるはずです。@property の行を数え、型修飾子を外し、どれが NSArray コンテナかを思い出しながら、形が合っていることを祈る。ここに Objective-C を貼り付ければ、整形式の XML が一度で返ってきます。単一の alloc/init スニペットでも、複数の @interface ブロックを含むヘッダーファイル全体でも、深くネストしたモデルでも、同じ結果が得られます。
単純な文字列置換ではありません。コンバーターは Cocoa が実際に XML にマッピングする動きをそのまま再現します。NSString の値はテキストノードになり(適切にエスケープされます)、NSNumber や NSDecimalNumber はラッパーを外してプレーンな数値テキストになります — たとえば [NSDecimalNumber decimalNumberWithString:@"249.99"] は 249.99 として出力されます。BOOL 値は true / false になり、スキーマが求めるなら YES / NO にもできます。NSArray<OrderItem *> は、要素型にちなんだ名前の子要素を持つコンテナ要素になります — NSXMLElement ツリーが出力するのと同じ形です。
インスタンス変数のバッキングも処理されます。@property が @synthesize customerName = _customerName; を使っていても、要素名は _customerName ではなく customerName のままです — iVar の命名は実装上の詳細であって、ワイヤーフォーマットの一部ではありません。ネストしたオブジェクト(Order に Address の @property があるような場合)はその場で展開され、nil の値は形を崩さないように空の要素になります。複数の @interface ブロックを貼り付けても、すべて出力に反映されます。.h ファイルに書かれているそのままの形で貼り付けて構いません — 下ごしらえは不要 — 結果を NSXMLDocument が生成するものと比べてみてください。
使い方
3 ステップ。1 つのクラスでも、ヘッダーをまとめて貼っても、やり方は同じです。
Objective-C を貼り付ける(またはサンプルを試す)
Objective-C を左のエディターにそのまま貼り付けてください。@interface ブロック、alloc/init のオブジェクトリテラル、複数クラス、ネストした型 — すべて OK。まず サンプルを読み込む を押すと、Order / OrderItem / Address の現実的な例を確認できます。
@property 属性を外したり、プラグマを削除したり、import 文を整理する必要はありません。Xcode で見たままにしておいてください。パーサーは実際の .h や .m ファイルの読み方を知っています。
変換を押す
緑の 変換 ボタンをクリックします。ツールは Objective-C を読み、すべての @property を残し、ネストしたオブジェクトも保ちながら、一度で XML を組み立てます。処理中は短いローディング表示が出ます。
XML をコピーする
右のパネルには、インデントの揃った整形式の XML が入ります — NSXMLParser を含め、標準準拠のパーサーならどれでも受け付けます。plist、SOAP リクエストのボディ、テストフィクスチャー、ドキュメントなどにコピーして使ってください。
本当に役立つ場面
iOS の plist フィクスチャーを作る
Objective-C のモデルに対応する Info.plist やシード用の plist が必要なとき。クラスを貼り付けて XML を取り出し、バンドルに入れるだけ — <code><dict></code> / <code><key></code> のペアを手書きする必要はありません。
Cocoa の XML 設定ファイル
古いデスクトップの Cocoa アプリは今でも XML 設定を配布します。<code>Settings</code> クラスを、それを読むコードと合うすぐ編集できるテンプレートに変えましょう。
iOS の古い SOAP / WCF クライアント
iOS アプリがまだ SOAP エンドポイントと通信しているなら、リクエスト契約クラスを貼り付けて XML エンベロープのボディを取得できます — <code>NSXMLElement</code> ツリーを手で組むより楽です。
Mac OS の XML ワークフローに投入
古い AppleScript / Automator / XML-RPC の連携は XML を期待します。Objective-C モデルを貼り付け、XML を取得し、そのままワークフローに流してください — 手動の翻訳は不要です。
よくある質問
@interface 宣言を一度に複数貼り付けてもいい?
はい。ヘッダーファイル丸ごと貼ってください。それぞれの @interface は、ネストした型を展開した状態で通ります。@interface が({ } の中で)ivar を明示的に宣言していても、モダンな @property のみのスタイルでも、どちらも同じように動きます。
@property の属性はどう扱われる?
(nonatomic, copy)、(strong)、(weak)、(readonly)、(assign) といった属性はランタイム向けのメタデータで、シリアライズされる形には影響しません。要素名はプロパティ名です。readonly のプロパティも出力されます(値は持ちます)。カスタムゲッターによる計算プロパティも、他のプロパティと同じ扱いです。
iVar の名前について — アンダースコア付きの要素になる?
いいえ。プロパティが customerName で、バッキング iVar が _customerName なら、XML の要素は <customerName> になります。アンダースコアは Objective-C の慣習であって、ワイヤーフォーマットではありません。要素名を変えたい場合は、@property 自体をリネームしてから貼り直してください。
NSString、NSNumber、NSDecimalNumber、BOOL、NSDate はどう扱われる?
NSString は適切に XML エスケープされたテキストノードになります。NSNumber と NSDecimalNumber はラッパーを外してプレーンな数値テキストになります。BOOL は true / false(ソースコードが plist 流儀なら YES / NO)になります。NSDate は ISO-8601 の文字列として出力されます。nil の値は削除されずに空の要素になります。
NSArray、NSDictionary、ネストしたオブジェクトはどうなる?
NSArray<OrderItem *> は、要素型にちなんだ名前の子要素を 1 件ずつ持つコンテナ要素になります: <items><OrderItem/><OrderItem/></items>。NSDictionary は <entry><key/><value/></entry> のコンテナになります。ネストしたオブジェクト(型が別の @interface のプロパティ)は、すべてのフィールドをそのままにその場で展開されます。
コードは保存される?
コードは変換のためにバックエンドへ送られますが、保存はされません — ペイロードをログに残すこともありません。オンラインツールの常として、本当に機密性が高いコードなら貼る前に目を通しておいてください。
一緒に使えそうなツール
Objective-C から XML はパズルの一片です。こちらのツールと組み合わせると便利です: