27

I have an objective C class like,

@interface message : NSObject {
 NSString *from;
 NSString *date;
 NSString *msg;
}

I have an NSMutableArray of instances of this message class. I want serialize all the instances in the NSMutableArray into a JSON file, using the new JSONSerialization APIs in iOS 5 SDK. How can I do this ?

Is creating a NSDictionary of each key, by iterating through each instance of the elements in the NSArray ? Can someone help with code of how to solve this ? I am not able to get good results in Google, as "JSON" skews the results to server-side calls and transfer of data instead of serialization. Thanks a lot.

EDIT:

NSError *writeError = nil; 
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:notifications options:NSJSONWritingPrettyPrinted error:&writeError];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 
NSLog(@"JSON Output: %@", jsonString);
0

4 Answers 4

41

EDIT: I have made a dummy app that should be a good example for you.

I create a Message class from your code snippet;

//Message.h
@interface Message : NSObject {
    NSString *from_;
    NSString *date_;
    NSString *msg_;
}

@property (nonatomic, retain) NSString *from;
@property (nonatomic, retain) NSString *date;
@property (nonatomic, retain) NSString *msg;

-(NSDictionary *)dictionary;

@end

//Message.m
#import "Message.h"

@implementation Message

@synthesize from = from_;
@synthesize date = date_;
@synthesize msg = mesg_;

-(void) dealloc {
    self.from = nil;
    self.date = nil;
    self.msg = nil;
    [super dealloc];
}

-(NSDictionary *)dictionary {
    return [NSDictionary dictionaryWithObjectsAndKeys:self.from,@"from",self.date,    @"date",self.msg, @"msg", nil];
}

Then I set up an NSArray of two messages in the AppDelegate. The trick is that not only does the top level object (notifications in your case) need to be serializable but so do all the elements that notifications contains: Thats why I created the dictionary method in the Message class.

//AppDelegate.m
...
Message* message1 = [[Message alloc] init];
Message* message2 = [[Message alloc] init];

message1.from = @"a";
message1.date = @"b";
message1.msg = @"c";

message2.from = @"d";
message2.date = @"e";
message2.msg = @"f";

NSArray* notifications = [NSArray arrayWithObjects:message1.dictionary, message2.dictionary, nil];
[message1 release];
[message2 release];


NSError *writeError = nil; 
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:notifications options:NSJSONWritingPrettyPrinted error:&writeError];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 
NSLog(@"JSON Output: %@", jsonString);

@end

The output when I run the application is thus:

2012-05-11 11:58:36.018 stack[3146:f803] JSON Output: [ { "msg" : "c", "from" : "a", "date" : "b" }, { "msg" : "f", "from" : "d", "date" : "e" } ]

ORIGINAL ANSWER:

Is this the documentation you are looking for?

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

7 Comments

The OP will first need to convert his object to a dictionary, but thats pretty straight forward(a static method will do the trick)
Damo: that page does not explain about converting an array of custom class to JSON. That is what I am struggling to find.
If all your class ivars are NSString then it should just magically work.... caveat: I have not tried this.
@Damo I get a runtime error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[message dictionaryRepresentation]: unrecognized selector sent to instance
@Damo NSError *writeError = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:notifications options:NSJSONWritingPrettyPrinted error:&writeError]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@"JSON Output: %@", jsonString); notifications is an NSMutableArray of message objects
|
8

Now you can solve this problem easily using JSONModel. JSONModel is a library that generically serialize/deserialize your object based on Class. You can even use non-nsobject based for property like int, short and float. It can also cater nested-complex JSON. It handles error checking for you.

Deserialize example. in header file:

#import "JSONModel.h"

@interface Message : JSONModel 
@property (nonatomic, strong) NSString* from;
@property (nonatomic, strong) NSString* date;
@property (nonatomic, strong) NSString* message;
@end

in implementation file:

#import "JSONModelLib.h"
#import "yourPersonClass.h"

NSString *responseJSON = /*from somewhere*/;
Message *message = [[Message alloc] initWithString:responseJSON error:&err];
if (!err)
{
   NSLog(@"%@  %@  %@", message.from, message.date, message.message):
}

Serialize Example. In implementation file:

#import "JSONModelLib.h"
#import "yourPersonClass.h"

Message *message = [[Message alloc] init];
message.from = @"JSON beast";
message.date = @"2012";
message.message = @"This is the best method available so far";

NSLog(@"%@", [person toJSONString]);

1 Comment

what if we want to serialize Array of messages using JSONModel?
2

Note: This will only work with serializable objects. This answer was provided above in an edit to the question itself, but I always look for answers in the "answers" section myself ;-)

- (NSString*) convertObjectToJson:(NSObject*) object
{
    NSError *writeError = nil;

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:&writeError];
    NSString *result = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

    return result;
}

2 Comments

Hi. How to convert array of NSObject. Thanks you :)
hey @kemdo - not sure - and I'm not doing ios dev anymore, so can't really say.... Good luck!
1

Here is a library i used in my projects BWJSONMatcher, which can help you easily match your json string up with your data model with no more than one line of code.

...
NSString *jsonString = @"{your-json-string}";
YourValueObject *dataModel = [YourValueObject fromJSONString:jsonString];

NSDictionary *jsonObject = @{your-json-object};
YourValueObject *dataModel = [YourValueObject fromJSONObject:jsonObject];
...
YourValueObject *dataModel = instance-of-your-value-object;
NSString *jsonString = [dataModel toJSONString];
NSDictionary *jsonObject = [dataModel toJSONObject];
...

Comments

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.