NSInvalidArgumentException,原因:'JSON写入中的类型无效(__NSDate)'

时间:2013-01-15 12:10:02

标签: iphone ios json nsdate

当我尝试JSON编码NSDate对象时,我收到此异常。我相信NSDate与JSON编码不兼容。但我必须编码date.Any解决方案?

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__NSDate)'

8 个答案:

答案 0 :(得分:12)

首先将您的数据存储在NSString中。然后将您的字符串转换为NSDate。

您可以参考SO:

Converting NSString to NSDate (and back again)

NSString to NSDate conversion problem

How to convert NSString to NSDate using NSDateFormatter?

答案 1 :(得分:7)

将NSDate转换为NSString并尝试编码。

- (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;
}

答案 2 :(得分:4)

你尝试过吗?

updateDate = [NSNumber numberWithFloat:[[NSDate date] timeIntervalSince1970]];

如此处所述:SDK not supporting NSDate objects

请按照以下步骤

进行操作

<强> 1。以JSON格式转换日期:

 NSDateFormatter *formatter = [[[NSDateFormatter alloc] init]autorelease];
 [formatter setDateFormat:@"Z"];
 NSString *updateDate = [NSString stringWithFormat:@"/Date(%.0f000%@)/", [[NSDate date] timeIntervalSince1970],[formatter stringFromDate:[NSDate date]]];

<强> 2。嵌入一​​些数组并POST数组。

答案 3 :(得分:4)

如上所述,您必须先将NSDate转换为NSString。但是,并不是很清楚,应该用哪种格式表示日期。答案可以找到here:“JSON本身没有指定日期应该如何表示,但是Javascript可以” - ISO8601。

以下是来自NSDate帮助程序类别的ISO8601转换方法,礼貌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;
}

如果您在JSON有效负载中获得ISO8601字符串并希望将其转换为NSDate,请将此类方法用于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)];
}

答案 4 :(得分:2)

在JSON中存储和检索NSDate对象的最简单方法是使用NSDate的 timeIntervalSince1970 属性。

返回的NSTimeInterval(double)非常标准,可以使用以下命令轻松转换回NSDate对象:

NSDate dateWithTimeIntervalSince1970:<#(NSTimeInterval)#>

答案 5 :(得分:0)

在尝试编码之前,必须将日期转换为字符串。到处都有足够的例子,所以应该很容易找到

答案 6 :(得分:0)

对于我们的情况,我们使用 Mantle 将对象转换为JSON,并且我们的一个属性NSDate的对象缺少其JSONTransformer

@property (nonatomic) NSDate *expiryDate;

其中:

+ (NSValueTransformer *)expiryDateJSONTransformer {
     return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *dateString, BOOL *success, NSError *__autoreleasing *error) {
        return [self.dateFormatter dateFromString:dateString];
    } reverseBlock:^id(NSDate *date, BOOL *success, NSError *__autoreleasing *error) {
        return [self.dateFormatter stringFromDate:date];
    }];
}

+ (NSDateFormatter *)dateFormatter {
    NSDateFormatter *df = [NSDateFormatter new];
    df.dateFormat = @"yyyy-MM-dd";
    return df;
}

答案 7 :(得分:0)

我正在我的身体参数编码器中做类似的事情

// handle dates
              var _params = [String: Any]()
              params.forEach { (key, value) in
                if let date = value as? Date {
                    _params[key] = DateFormatter.iso8601Full.string(from: date)
                } else {
                    _params[key] = value
                }
              }

              return try? JSONSerialization.data(withJSONObject: _params)