5

How to serialize the following class in objective-c so that it can be used with SBJson?

I get "JSON serialisation not supported for Animal" error when I use this code.

Can someone point out where I am going wrong?

The contents of Animal.h file is as below

#import <UIKit/UIKit.h>

@interface Animal : NSObject<NSCoding> {
    NSString *name;
    NSString *description;
    NSString *imageURL;
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *description;
@property (nonatomic, retain) NSString *imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u;

@end

The contents of Animal.m file is as below

#import "Animal.h"

@implementation Animal
@synthesize name, description, imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
    self.name = n;
    self.description = d;
    self.imageURL = u;
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if(self = [super initWithCoder:aDecoder])
    {
        name = [[aDecoder decodeObjectForKey:@"name"] retain];
        description = [[aDecoder decodeObjectForKey:@"description"] retain];
        imageURL = [[aDecoder decodeObjectForKey:@"imageURL"] retain];
    }
    return [self initWithName:name description:description url:imageURL];
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [super encodeWithCoder:encoder];
    [encoder encodeObject:name forKey:@"name"];
    [encoder encodeObject:description forKey:@"description"];
    [encoder encodeObject:imageURL forKey:@"imageURL"];
}    

@end
Billy Samuel
  • 672
  • 2
  • 6
  • 21

7 Answers7

9

Make your custom class conform to NSCoding protocol and then serialize it.

For more info, visit the Apple documentation

Also, this link will also help you. As suggested in this link, archive your custom class to NSData and serialize that as provided in the Apple documentation.

Edit Make your Animal.m as follows:

#import "Animal.h"

@implementation Animal
@synthesize name, description, imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
    self = [super init];
    if( self )
    {
       self.name = n;
       self.description = d;
       self.imageURL = u;
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if( self )
    {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.description = [aDecoder decodeObjectForKey:@"description"];
        self.imageURL = [aDecoder decodeObjectForKey:@"imageURL"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:name forKey:@"name"];
    [encoder encodeObject:description forKey:@"description"];
    [encoder encodeObject:imageURL forKey:@"imageURL"];
}    

@end
Ilanchezhian
  • 17,426
  • 1
  • 53
  • 55
  • The second link is the key. You use `[NSKeyedArchiver archivedDataWithRootObject:(id)]` and `[NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)]` to serialize and unserialize objects. – respectTheCode Sep 17 '12 at 15:58
4

To actually answer your question on how to do it using SBJson: Implement the proxyForJson method. Unless you are serializing an NSArray or NSDictionary you must override this method for serialization to work.

You can see that this is the case by looking at the SBJson source code (in SBJsonWriter.m):

- (NSData*)dataWithObject:(id)object {    
...   
    if ([object isKindOfClass:[NSDictionary class]])
                ok = [streamWriter writeObject:object];

            else if ([object isKindOfClass:[NSArray class]])
                ok = [streamWriter writeArray:object];

            else if ([object respondsToSelector:@selector(proxyForJson)])
                return [self dataWithObject:[object proxyForJson]];
            else {
                self.error = @"Not valid type for JSON";
                return nil;
            }
    ...
    }
}

Implement proxyForJson in Animal.m like this (not tested):

- (NSDictionary*) proxyForJson
{
return [NSDictionary dictionaryWithObjectsAndKeys:self.name, @"name",
                                                  self.description, @"description",
                                                  self.imageURL, @"imageURL", 
                                                  nil];
}
aspartame
  • 4,622
  • 7
  • 36
  • 39
3

This open source project JSONCoding makes the whole process pretty simple, using the new sdk class in conjunction with the NSCoding protocol.

Rob
  • 11,446
  • 7
  • 39
  • 57
3

Check the newly introduced NSJSONSerialization class:

NSJSONSerialization class

sohail.hussain.dyn
  • 1,411
  • 1
  • 16
  • 26
jcm
  • 1,781
  • 1
  • 15
  • 27
2

I think you can check out this if it helps you: Make a Custom Class Serializable

Community
  • 1
  • 1
B25Dec
  • 2,301
  • 5
  • 31
  • 54
  • I have added the following methods as said in this link, but still I am getting the error message as "JSON serialisation not supported for Animal" - (id)initWithCoder:(NSCoder *)aDecoder; - (void)encodeWithCoder:(NSCoder *)encoder; – Billy Samuel Jan 19 '12 at 09:04
  • i think nscoding is a protocol and we should implement in this way but still if you are not getting my point then chekc out this one http://www.raywenderlich.com/1914/how-to-save-your-app-data-with-nscoding-and-nsfilemanager here is the purpose is different of the tutorial but the use of nscoding you can learn from here i think .. – B25Dec Jan 19 '12 at 09:22
  • I have updated the original question with the source code along with the changes suggested in the links that you have shared. – Billy Samuel Jan 19 '12 at 11:14
1

Please check this Property List Programming Guide - Serializing a Property List

and the similar post here: Make a Custom Class Serializable in Objective-c/iPhone?

Object serialization in XML format using Obj-C / iPhone SDK

Community
  • 1
  • 1
Meet
  • 4,904
  • 3
  • 24
  • 39
  • I have added the following methods as said in the post "Make a Custom Class Serializable in Objective-c/iPhone?", but still I am getting the error message as "JSON serialisation not supported for Animal" - (id)initWithCoder:(NSCoder *)aDecoder; - (void)encodeWithCoder:(NSCoder *)encoder; – Billy Samuel Jan 19 '12 at 06:45
  • Did you make the class conform to `NSCoding` protocol? – Ilanchezhian Jan 19 '12 at 07:18
  • I am new to writing code for IPhone app. Can you look at the source code in my orginal question and point out where I am going wrong? – Billy Samuel Jan 19 '12 at 11:20
0

See also https://github.com/jsonmodel/jsonmodel

Magical Data Modeling Framework for JSON - allows rapid creation of smart data models. You can use it in your iOS, macOS, watchOS and tvOS apps.

This is also the chosen library for the Objective-c Swagger client.

Alex Nolasco
  • 18,750
  • 9
  • 86
  • 81