While working on Destro I got really fed up with NSKeyedArchiver. It’s a huge PITA to create a domain model, then spend at least four times the amount you spent on making the domain model on boilerplate code to be able to archive/unarchive your classes. Unlike Java, where serialization is a matter of implementing a tagging interface (e.g. no behavior), in Objective-C you must specify for each property how exactly you want to serialize/deserialize it. You must specify the property’s type as well as the key under which to store it. And then do it again for the retrieval part. In 99.999% of the time, I want to serialize a property as its own type (you know, the one you already specified in your interface definition). The same applies for the key under which to store it: I simply use the property name (you know, the one you also already specified in your interface definition). Besides not having a default archiving strategy, there is also no editor support whatsoever for this in XCode.
Now wouldn’t it be nice if you were to simply have a method where you stick in a random object (tree) and get an XML string out? And to have another method where you put in an XML String, a Class type and then have that method repopulate and reinstantiate the whole object tree? I investigated some of the XML parses/frameworks, but none seem to be able to parse/generate a tree properly (not without first populating the tree with objects yourself or knowing the exact document/object structure in advance). Time for some extension then!
It took me a few hours (not spent on Destro itself, but I find this very much worth the effort), but I now have exactly such a class. It features two methods:
- +(NSString *)objectToXml:(id)objectToEncode;
- +(id)xmlToObject:(NSString *)xmlString targetClass:(Class)targetClass;
The first method takes any object (tree), and traverses it using the Objective-C runtime (introspection/reflection, or whatever you wish to call it), creating an XML tree in the process. The result is a nicely readable and portable XML document string.
The second method takes an XML document string and parses it into the specified target class. Again, it uses the Objective-C runtime to traverse the object, instantiate objects and fetch the corresponding elements from the XML document using XPATH.
Both methods are based on Googles excellent GDataXML, which is in turn based on libxml2. I still have to implement a few datatypes, make the code more robust, and clean up the code a bit, but expect this to pop up on a public source repository near you very soon!