NSInvalidArgumentException, reason: 'Invalid type in JSON write (__NSDate)' NSInvalidArgumentException, reason: 'Invalid type in JSON write (__NSDate)' json json

NSInvalidArgumentException, reason: 'Invalid type in JSON write (__NSDate)'


Convert NSDate to NSString and try to encode.

- (NSString *) changeDateToDateString :(NSDate *) date {    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];    [dateFormatter setTimeZone:[NSTimeZone localTimeZone]];    NSLocale *locale = [NSLocale currentLocale];    NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:@"hh mm" options:0 locale:locale];    [dateFormatter setDateFormat:dateFormat];    [dateFormatter setLocale:locale];    NSString *dateString = [dateFormatter stringFromDate:date];    return dateString;}


As noted, you must first convert your NSDate to an NSString. It's not immediately clear, however, which format the date should be represented in. The answer can be found here: "JSON itself does not specify how dates should be represented, but Javascript does" -- ISO8601.

Here is an ISO8601 conversion method from a helper category for NSDate, courtesy Erica Sadun:

- (NSString *)ISO8601 {    struct tm time;    time_t interval = [self timeIntervalSince1970];    gmtime_r(&interval, &time);    char *x = calloc(1, 21);    strftime_l(x, 20, "%FT%TZ", &time, gmtlocale);    NSString *string = [NSString stringWithUTF8String:x];    free(x);    return string;}

If you get an ISO8601 string back in a JSON payload and want to convert it to an NSDate, use this class method for NSDate:

+ (NSDate *)dateFromISO8601:(NSString *)string {    if(!string) return nil;    if (![string isKindOfClass:[NSString class]]) return nil;    struct tm time;    strptime_l([string UTF8String], "%FT%TZ", &time, gmtlocale);    return [NSDate dateWithTimeIntervalSince1970:timegm(&time)];}