【问题标题】:NSInvalidArgumentException, reason: 'Invalid type in JSON write (__NSDate)'NSInvalidArgumentException,原因:'JSON 写入中的类型无效(__NSDate)'
【发布时间】:2012-12-29 12:47:25
【问题描述】:

我在尝试对 NSDate 对象进行 JSON 编码时遇到此异常。我认为 NSDate 与 JSON 编码不兼容。但我必须对日期进行编码。有什么解决方案吗?

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

【问题讨论】:

    标签: iphone ios json nsdate


    【解决方案1】:

    我在我的身体参数编码器中做这样的事情

    // 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)
    

    【讨论】:

      【解决方案2】:

      对于我们的例子,我们使用 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;
      }
      

      【讨论】:

        【解决方案3】:

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

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

        NSDate dateWithTimeIntervalSince1970:<#(NSTimeInterval)#>
        

        【讨论】:

          【解决方案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。嵌入某个数组并发布该数组。

          【讨论】:

          • 你到底为什么要使用浮点数? float 具有 24 位精度。自 1970 年以来已经有超过 10 亿秒。这意味着您的分辨率比一分钟还差。您的日期格式绝对不标准。
          【解决方案5】:

          如上所述,您必须首先将您的 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)];
          }
          

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

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

                你可以参考一下:

                Converting NSString to NSDate (and back again)

                NSString to NSDate conversion problem

                How to convert NSString to NSDate using NSDateFormatter?

                【讨论】:

                • 这没有意义。 OP 正在询问如何编码 NSDate。这意味着他们应该先将 NSDate 转换为 NSString,然后再将其插入到他们尝试进行 JSON 编码的字典中。我在下面的回答显示了一个示例解决方案。
                • 不是一个好的解决方案。它只是一个旁路。我需要知道如何使它与 NSDate 本身一起工作,或者如果没有,为什么会发生这种情况。
                猜你喜欢
                • 1970-01-01
                • 2017-03-12
                • 1970-01-01
                • 2017-07-05
                • 1970-01-01
                • 1970-01-01
                • 2014-09-18
                • 2015-11-16
                • 2019-10-26
                相关资源
                最近更新 更多