2

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

2
  • I don't think I understand name of the variable - can you add an example JSON output please? Commented Jun 1, 2012 at 9:40
  • check this QA stackoverflow.com/questions/9139454/… Commented Jun 1, 2012 at 9:47

2 Answers 2

2

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

Here is a sample.

Sign up to request clarification or add additional context in comments.

4 Comments

To get that into JSON, would also have to implement your own JSONArchiver class?
i followed the tutorial, but the result is (null)
OP wants to serialize to JSON, which this solution does not describe.
@Ev. Well, it answers what is asked. If not with NSCoding protocol how will you serialise a complex object?. Could you please explain?. The coding methods you write define the JSON.
1

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.

1 Comment

Thank you for your detailed explanation. I ended up writing my own encoder, it took a little more time than expected, but i think it's a the best possible solution for now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.