views:

2659

answers:

8

Apple provides the NSArchiver and NSUnachriver for object serialization / deserialization, but this can not handle any custom xml schema. So filling an object structure with the data of any custom xml schema has to be made manually. Since the iPhone developer community is rapidly growing, a lot of newbie programmer are despairing to deal with the available xml parsing possibilities.

The iPhone SDK only provides NSXmlParser for xml parsing, which is more useful to read certain parts of an xml file, than filling a whole object structure, which really is a pain.

The other possibility is the famous libxml library, which is written in ANSI C - not easy to use for someone who starts programming with objective-c and never learned proper C before. Event there are a lot of wrappers available, dealing with xml can be a pain for newbies.

And here my idea takes place. An XmlSerializer library which fills an object structure automatically could makes it a lot easier and increase the app quality for many programmers. My Idea should work like this:

The xml file

<Test name="Michael" uid="28">
    <Adress street="AlphaBetaGammastrasse 1" city="Zürich" postCode="8000" />

  <Hobbies>
    <Hobby describtion="blabla"/>
    <Hobby describtion="blupblup"/>
  </Hobbies>
</Test>

The classes to fill

@interface Test : NSObject {
    NSString *name;
    Adress *adress;
    NSArray *hobbies;
    int uid;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) Adress *adress;
@property (nonatomic, retain) NSArray *hobbies;
@property (nonatomic, readwrite) int uid;
@end

@interface Adress : NSObject {
    NSString *street;
    NSString *city;
    int postCode;
}
@property (nonatomic, copy) NSString *street;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, readwrite) int postCode;
@end

How the xml serializer should work

NSError *error = nil;
XMLSerializer *serializer = [[XMLSerializer alloc] init];
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TestFile" ofType:@"xml"]];
Test *test = [serializer deserializeWithData:data error:&error];

To fill the object structure needs only one line of code:

Test *test = [serializer deserializeWithData:data error:&error];

This would be so easy to use that any newbie programmer could use it. For more advanced usage the serializer could be configurable.

What do you think, would this be a helpful and popular library for iPhone and OSX Applications?

Edit: You can see the project here, but it is fare away from release.

+2  A: 

Good morning, Enrya

Your idea about an XML serialization/deserialization module for iPhone is great!

We develop applications for mobile devices, mainly using java (JavaSE and ANDROID) and use XStream to process XML responses from web services.

For funcionality, XStream could be a reference. See xstream.codehaus.org for more info.

Actually, I am using NSXMLParser and specific classes for XML data, received from web services, but will keep your idea in mind. Unfortunately, lack of time is a problem.

Thanks for sharing this proposal! Alexander

Alexander
Yes indeed, I have my inspiration from xstream :)
Enyra
A: 

This is a quite good idea, implementation wise I would do it by implementing NSXMLArchiver and NSXMLUnarchiver as subclasses of NSCoder. This way any class conforming to the NSCoding protocol could easily be serialized to and from XML.

One performance hit when serializing to XML will be the primitive values as attributes, because you can not guarantee the order an object will request data to be encoded. So if attributes is what you want, then it will be quite huge in memory buffers. But it would be a fun exercise.

As for how popular it would be? Not so popular I think. The use-case just is too small.

  • Device-to-device - Simply using NSKeyedArchiver is way easier, and MUCH more compact.
  • Device-to-new server - The new server would have to implement the same scheme as well, serializing to Java, C# or whatever.
  • Device-to-existing server - The XML format is already fixed, and most probably not close to this.
PeyloW
A: 

What you are describing is buried inside of the ObjectiveResource implementations, and it supports both JSON and XML. It should be pretty easy to fork that and slim it down to just the parsing by throwing out all the connection management.

slf
+2  A: 

The NSKeyedArchiver works precisely because it doesn't try to map onto an XML schema. Many, many XML schemas are badly designed (i.e. they're translating an in-memory object structure to an external representation format). The key problem is that the documents should be designed to make sense from a document perspective, and that that would then need to map onto whatever memory layout you wanted for your objects. Ever seen XML documents with lots of 'refid' attributes referring to other parts of the doc? Those are usually transliterated from a relational database which is just sticking angled brackets on the resultset.

So starting by assuming a one-to-one mapping between an XML document and its code representation is pretty much doomed in all but the simplest cases. Just consider where we would be today with HTML if it had been designed around the C++ objects that were used to instantiate the document in the first browser ... (well, more like Objective-C, but hey ...)

The point about NSKeyedArchiver is that you can evolve the data structure without breaking the ability to load older versions. It's unbelievably difficult to do that (properly) using some kind of automated instance-var-to-element mapping.

AlBlue
A: 

I've been struggling with requirements in this domain and think it would be a great idea. I've had to bully my dot net services to return JSON for easy consumption on an iPhone. A decent serialization library would be superb.

Andiih
+1  A: 

Hi,

I have started a similar open source project. I have named it SAMIXOS. you can visit this page and try it. Its in initial development. It works similar to what Enyra has asked.

Soon i will provide a sample code.

http://sourceforge.net/projects/samixos/

Sami

Sami
A: 

Hi,

I want to convert an image to base64 string in objective-c. Can any one help.

What I am doing is:

UIImage *pickedImage=[UIImage imageNamed:@"test.jpg"]; NSData *topImageData = UIImageJPEGRepresentation(pickedImage, 1.0); NSString *myString=[topImageData base64EncodedString];

I am able to get the base64 string. But when I pass it through JSON request to a java server. Server is able to decode. But the image is different.

That means some thing is wrong. My guess is here we are changing UImage to NSData and then converting to base64. At Java end they are directly converting base64 string to image....

Please any one help me in this issue.

Thanks Shiva

Shiva
A: 

Hi,

I have opened a related open source project, a simple XML serializer (a'la kXML and StAX serializers from the Java world).

http://code.google.com/p/xswi/

In my experience, cost-effective tools for mapping objects from one model (objects in memory) to another model (some XML Schema) do not exist, since the logic still has to be expressed somehow. You are better off doing the work using tools (code!?) you are familiar with.

But if you insist on using such a tool, then make your objects model the same as the XML model.

Thomas

Thomas