How do I JSON serialize an NSDate Dictionary in JSONKit
Asked Answered
E

2

10

I tried this using Jsonkit and Apple's JSON serializer with no luck. It keeps breaking on the geo property, which is an nsarray of NSNumbers.

Post* p = [[Post alloc] init];

    p.uname = @"mike";
    p.likes =[NSNumber numberWithInt:1];
    p.geo = [[NSArray alloc] initWithObjects:[NSNumber numberWithFloat:37.78583], [NSNumber numberWithFloat:-122.406417], nil ];
    p.place = @"New York City";
    p.caption = @"A test caption";
    p.date = [NSDate date];


 NSError* error = nil;

    NSString* stuff = [[p getDictionary] JSONStringWithOptions:JKParseOptionNone error:&error];

UPDATE: Checking on the error it's the NSDate that it fails on, not the NSArray. How do I pass in the date formatter into the function?

UPDATE 2: Solved- ok looked at the latest commit for jsonkit and saw that you could do this:

 NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
    [outputFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZ"];

    NSString* result = [p.dictionary JSONStringWithOptions:JKSerializeOptionNone serializeUnsupportedClassesUsingBlock:^id(id object) {
        if([object isKindOfClass:[NSDate class]]) { return([outputFormatter stringFromDate:object]); }
        return(nil);
    } error:nil];

which seems to have worked but note that this feature for JSONKit is WIP so it could change in the next official release.

Exteroceptor answered 13/12, 2011 at 18:19 Comment(9)
What do you mean when you say "it keeps breaking"? Is it a crash? Is it not creating JSON strings as you expect? What are you seeing?Adelladella
I'd suggest trying to get JSONKit or the JSON serializer in iOS5 working rather than rolling your own parser so to speak. What issues were you having with JSONKit?Jurel
I tried the above code with JSONKit, in returns nil when I call both JSONDATA and JSONString. If I leave out the NSArray it works fine. If I serialize just the nsarray it works fine returning the correct serialization... it only seems to be an an issue if I have an nsarray as a value in the nsdictionary and I try to serialize the nsdictionary.Exteroceptor
Are you checking the error returned?Phillipp
Show us your getDictionary method, and show us what is in error after JSONStringWithOptions:error: returns.Faa
I'm guessing that your Post getDictionary is broken somehow.Glover
(You know, of course, you can NSLog an NSDictionary and get a "JSON-like" dump that will show you if there's anything wrong in your setup. That and the error info should nail your problem right away.)Glover
Ok, I was initially calling it without the parameterless function so forgot about the error... it was the NSDate that it was failing on, not the array. How do I pass a date formatter to the serializer?Exteroceptor
For what it's worth, here's the "bug" discussion around NSDate support -- github.com/johnezang/JSONKit/issues/52Eyla
A
7

Hmmmm -- can't speak for JSONKit or iOS5 -- I use Stig's SBJSON framework. Using it the implementation is fairly succinct:

@implementation Post

- (id) initWithName:(NSString*)Name :(NSNumber*)Likes :(NSArray*)Geo :(NSString*)Place :(NSString*)Caption :(NSDate*)Date {

   if ((self=[super init])==nil) {
       return nil;
   }
   uname = Name;
   likes = Likes;
   geo = Geo;
   place = Place;
   caption = Caption;
   date = Date;
   return self;
}

- (NSDictionary*) getAsDictionary {
   NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
   [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
   NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
   [dateFormatter release];

   NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:uname,@"uname",
                      likes,@"likes",
                      geo,@"geo",
                      place,@"place",
                      caption,@"caption",
                      dateString,@"date",
                      nil];
   return dict;
}

@end

and

- (void)viewDidLoad {
    [super viewDidLoad];

    Post* post = [[Post alloc] initWithName:@"Mike" 
                                       :[NSNumber numberWithInt:1] 
                                       :[[NSArray alloc] initWithObjects:[NSNumber numberWithFloat:37.78583], [NSNumber numberWithFloat:-122.406417],nil] 
                                       :@"New York City" :@"A Test caption" 
                                       :[NSDate date]];

    SBJsonWriter *writer = [[SBJsonWriter alloc] init];
    NSString* json = [writer stringWithObject:[post getAsDictionary]];
    if (json == nil) {
        NSLog(@"error = %@",writer.errorTrace);
    }
    NSLog(@"json = %@",json);
    [writer release];
    [post release];
}

produces

TestJSON[52337:207] json = {"likes":1,"date":"2011-12-13 11:12:57","place":"New York City","caption":"A Test caption","uname":"Mike","geo":[37.78583,-122.4064]}

Allayne answered 13/12, 2011 at 20:5 Comment(1)
Just in case someone doesn't notice, the dateFormatter format is not correct. Minutes are defined using 'mm', not 'MM'.Diophantus
T
0

You have to multiply the number of seconds by 1000 to get the correct long number to send to your server side (or whatever).

[NSNumber numberWithLongLong:[yourDate timeIntervalSince1970]*1000]

Example :

NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:uname,@"uname",
                      likes,@"likes",
                      geo,@"geo",
                      place,@"place",
                      caption,@"caption",
                      [NSNumber numberWithLongLong:[yourDate timeIntervalSince1970]*1000],@"date",
                      nil];
Trilly answered 8/1, 2013 at 15:34 Comment(1)
only if your server is expecting millisecondsFollansbee

© 2022 - 2024 — McMap. All rights reserved.