Zoltan Varadi
Zoltan Varadi

Reputation: 2478

Objective-C serialize list of complex objects

I have a list of classes looking like this:

@interface AISlideItem: NSObject
{
    NSString*  PlaceHolderName;
    NSUInteger PlaceHolderID;
}
@property (nonatomic, strong) NSString* PlaceHolderName;
@property (nonatomic) NSUInteger PlaceHolderID;

@end

@interface AITitleSlideItem : AISlideItem
{
    NSString* Title;
}
@property (nonatomic, strong) NSString* Title;
@end

@interface AIParagraphSlideItem : AISlideItem
{
    NSMutableArray* Paragraphs;
}
@property (nonatomic, strong) NSMutableArray* Paragraphs;
@end

@interface AITextSlideItem : AISlideItem
{
    NSString* Text;
}
@property (nonatomic, strong) NSString* Text;
@end

@interface AIPictureSlideItem : AISlideItem
{
    NSMutableData* Picture;
}
@property (nonatomic, strong) NSMutableData* Picture;
@end

@interface AISlideContent : NSObject
{
    NSString*       LayoutName;
    NSMutableArray* Items;
}
@property (nonatomic,strong) NSString* LayoutName;
@property (nonatomic,strong) NSMutableArray* Items;
@end

@interface ContentParaghraph : NSObject
{
    NSInteger Level;
    NSString* Text;
}
@property (nonatomic) NSInteger Level;
@property (nonatomic, strong) NSString* Text;
@end

I want to serialize into json an NSMutableArray holding AISlideContent objects. Every item's name in the json should be the same as the name of the variable.

How can I do that?

This is an example JSON:

{
  d: [
     {
          Items: [
          {
              placeHolderName: "1",
              Title: "Title Slide"
          },
          {
              placeHolderName: "2",
              Paragraphs: [
                 {
                     Level: 0,
                     Text: "Title content"
                 }
              ]
          }
       ],
       LayoutName: "Title"
     },
     {
         Items: [
         {
              placeHolderName: "1",
              Title: "Slide 2"
     },
     {
              placeHolderName: "2",
              Paragraphs: [
              {
                 Level: 0,
                 Text: "Line 1"
              },
              {
                 Level: 0,
                 Text: "Line 2"
              },
              {
                 Level: 1,
                 Text: "Line 2 indented"
              },
              {
                 Level: 2,
                 Text: "Line 3 more indented"
              },
              {
                 Level: 0,
                 Text: "Line 4"
              }
              ]
     }
      ],
      LayoutName: "Title and Content"
     },
     {
           Items: [
           {
                placeHolderName: "1",
                Title: "Slide 3"
           },
           {
                placeHolderName: "3",
                Picture: [

                ]
           }
       ],
       LayoutName: "Picture above Caption"
      }
      ]
}

p.s. I have ARC enabled

Upvotes: 2

Views: 1960

Answers (2)

Vignesh
Vignesh

Reputation: 10251

you have to follow NSCoding protocol and override encodeObject and decodeObject method.

Here is a sample.

Upvotes: 2

CouchDeveloper
CouchDeveloper

Reputation: 19096

Objective-C JSON libraries define the mapping between Objective-C classes and the corresponding JSON elements. For example, a NSArray will be mapped to a JSON Array, a NSDictionary will be mapped to a JSON Object, a NSString to a JSON String and so force.

An implementation of a JSON serializer will walk the object hierarchy and either figure the Objective-C class type using introspection, or internally implement a Category for those Objective-C classes which can be serialized, and then invoking/calling the appropriate serialization method in order to write the characters into a stream.

Now, having an object hierarchy containing objects with arbitrary classes and trying to run the serializer will likely fail, since it doesn't know how to serialize a NSDate for example.

A possible solution to this problem is to take a look at the documentation of the JSON library you are using and figure out if and how this can be accomplished. AFAIK, Cocoa's built-in NSJSONSerialization cannot do this.

Recent JSONKit may work for you, which uses a callback mechanism. I didn't look too deep into it, though.

JPJson library on the other hand uses the Category approach. You simply define a Category for your custom class respectively a built-in Cocoa class which you want to serialize (e.g. NSDate) and implement a protocol. Once implemented (which is quite easy in JPJson) objects of this class will be correctly serialized even within a deeply nested hierarchy, maintaining other serialization options - like "pretty printing", Unicode encoding, string escaping, etc.

Looking at your example, it seems quite easy to implement with JPJson. The JPJson package is on GitHub and also has a sample which shows how to serialize those custom classes.

You may take a look at https://github.com/couchdeveloper/JPJson and especially Sample6.

Upvotes: 1

Related Questions