LinkedInAttic/Isaac

Support NSDate

Closed this issue · 10 comments

I just wonder if we want to support NSDate?

Interesting question. I'm not sure. Here's what I've found:

  1. JSON specification has no mention of dates and doesn't specifically support them (http://www.json.org/)
  2. JSONKit and NSJSONSerialization do not seem to return NSDates as part of the dictionaries and arrays they return.

So, first, what's your use case for this? Does your parser form dates automatically?

Second, I first thought this would be supported. Maybe there's nothing special about NSDates, but possibly we could handle nonJSON values more gracefully? What I'm thinking is, if it's not a string, number, array or dictionary, then if the types match, just set the object on the model. This would give support to NSDate and any other 'custom JSON object'.
So if you have a dictionary filled with objects of type A, and your model has a property of type A, just set the value?

I agree. It's not a basic type of JSON. We support JSON to model data binding, so I was hoping there are some magic to handle common types, e.g. NSDate.

I start using it to bind my model and store them as JSON somewhere, and there is a date field in my data model. I need to write some code the correctly handle date.

Another interesting case would be that supporting serialize / deserialize for multiple classes in one JSON. That's say I have a Class A, and there is an array of Class B. interestingly, we can generate a correct JSON, but we have no way to read it back. Unless I miss som API in the document.

By the way, this project did save me a lot of time!! I use it with underscorem, and my parsing JSON code become so awesome!!

Btw, some Java JSON binding library actually handle date as string. It will serialize into UTC string into JSON, and read it back as Date.

Oh, ok. Yes. I see what you're saying. I wonder where this code belongs and how to make it generic.
It'd be pretty easy to add. We already do some similar stuff for strings and ints. If the JSON has an int but the model has a string, it just converts it on the fly. Sounds like we're looking for something similar.

My main concern is how to handle different formats and not do anything that people don't want us to do. I'm guessing we could use an NSDateDetector on strings and just return the first date found. For converting timestamps to dates, I'm not sure its possible because of the different standards for timestamps?

What format are you currently using to send down your date in the JSON? Is it a string? If so, what does it look like?

Hi there, I was looking for the answer for this but I figured it out. Using this code snippet you can specify your own date formatter and override the date field and make it conform to whatever you're looking for

-(void)isc_setJSONValue:(id)jsonValue forJSONKey:(NSString *)jsonKey {
    if([jsonKey isEqualToString:@"createdAt"]) {
        NSDate* date =
         [[BaseModel dateFormat] dateFromString:jsonValue];
        [self setWithDateValue:date forObjectKey:jsonKey];
    } else {
        [super isc_setJSONValue:jsonValue forJSONKey:jsonKey];
    }
}

- (void)setWithDateValue:(NSDate *)jsonDateValue forObjectKey:(NSString *)objectKey {
//Add custom logic to validate the date field 
    [self isc_safeSetValue:jsonDateValue forKey:objectKey];
}

static NSDateFormatter *dateFormatter;
+(NSDateFormatter*)dateFormat
{
    if(!dateFormatter)
    {
        dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
    }
    return dateFormatter;
}

Also if you want to turn the date back into a string be sure to put this somewhere

@implementation NSDate (IsaacObjectToJSON)

- (NSString *)isc_jsonRepresentation {
    NSString* dateString;
    dateString = [[BaseModel dateFormat] stringFromDate:self];

    return dateString;
}

@end

Sorry for the long response. I think this is the right solution, and avoids adding extra unnecessary functionality to the library.

Woot awesome