Swift JSON 序列化类型不匹配

Posted

技术标签:

【中文标题】Swift JSON 序列化类型不匹配【英文标题】:Swift JSON Serialization typeMismatch 【发布时间】:2018-10-15 01:18:59 【问题描述】:

目前正在努力如何使用 Decodable。我已经对我遇到的错误进行了一些谷歌搜索,但我仍然相信我构建结构的方式不正确,但对我来说似乎很有意义。

我也尝试过使用可选项

在我最后发布的错误中,我对 Double 类型的引用感到困惑。因为我没有任何类型或任何使用双精度的响应。

(我还可以使用将数据转换为字典的旧 swift 方法来序列化 json 响应 - [String : Any]。但我想使用现代/更新的方法。)

JSON 响应

    "NEWS":
  [
    
      "DATE":"2018-10-13T03:56:06+1000",
      "SOURCE":"smh.com.au",
      "BLURB":"Assistant Treasurer Stuart Robert says he has repaid $37,975 of \"excess usage charges\" in home internet bills footed by taxpayers.",
      "ID":102347,
      "TITLE":"Stuart Robert pays back $38,000 in excessive home internet charges"
    ,
    
      "DATE":"2018-10-12T18:00:38+1000",
      "SOURCE":"itwire.com",
      "BLURB":"The CVC costs set by the NBN Co make it very difficult for ISPs to offer gigabit connections to more than a select band of customers who are willing to sign up in numbers and pay slightly more than other speed tiers, according to one ISP who caters to this type of consumer.",
      "ID":102343,
      "TITLE":"NBN gigabit connections will remain mostly a pipe dream",
    
      "DATE":"2018-10-12T09:48:43+1000",
      "SOURCE":"computerworld.com.au",
      "BLURB":"The Department of Home Affairs has rejects calls to include independent judicial oversight of the decision to issue Technical Assistance Notices and Technical Capability Notices as part of proposed legislation intended to tackle police agencies’ inability to access encrypted communications services.",
      "ID":102342,
      "TITLE":"Home Affairs rejects calls for additional safeguards in ‘spyware’ law"
    ,
    
    "DATE":"2018-10-11T12:16:05+1000",
    "SOURCE":"itnews.com.au",
    "BLURB":"NBN Co is hoping to “speed up” building works on the fibre-to-the-curb (FTTC) portion of its network as it tries to make up lost ground.",
    "ID":102334,
    "TITLE":"NBN Co says fibre-to-the-curb build is more complex that it hoped"
    ,
  ]

代码

struct Root: Decodable 
    let news: [News]?

    enum CodingKeys: String, CodingKey 
        case news = "NEWS"
    



struct News: Decodable 
    let date: Date
    let source, blurb: String
    let id: Int
    let title: String

    enum CodingKeys: String, CodingKey 
        case date = "DATE"
        case source = "SOURCE"
        case blurb = "BLURB"
        case id = "ID"
        case title = "TITLE"
    

序列化

URLSession.shared.dataTask(with: url)  (data, response, err) in  
guard let dataStr = data else 
            return
        
do 
    let root = try JSONDecoder().decode(Root.self, from: dataStr) //error is caught here
    guard let r = root else  return 
    print(r.news)
 catch let err 
    print("JSON Error - \(err)")

.resume()

错误

错误序列化 json typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "NEWS", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys( stringValue: "DATE", intValue: nil)], debugDescription: "预期解码 Double,但找到了字符串/数据。",underlyingError: nil))

【问题讨论】:

【参考方案1】:

这是因为 Date 的默认编码策略是 double (自纪元以来的秒数)。您可以将默认策略更改为 iso8061 或任何自定义。例如,您可以像这样在解码器中设置日期格式化程序:

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

【讨论】:

就是这样。谢谢! 谢谢 :) 我已经花了半个小时来看看出了什么问题。 iso8601数据解码后工作正常【参考方案2】:

将 JSON 放入 Quicktype 会给我一个额外的逗号错误。除非json文件有更多节点?所以首先要确定这一点。乍一看,我可能是错的,但我认为您必须格式化 DATE 才能完全匹配。

【讨论】:

感谢您的回复。是的,日期有问题(我已经从结构中删除了日期并且它正在正确序列化),但是 JSON 很好,我可能格式不正确

以上是关于Swift JSON 序列化类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 的序列化器 JSON 出错 - AutoreleasingUnsafePointer(有 1 个孩子)

验证 JSON 是不是匹配类型

类型不匹配 Swift JSON

如何检查 Json 是不是匹配特定的 C# 类型?

Swift JSON解码器类型不匹配错误

是否有可能在反序列化时以某种方式捕获与任何 POCO 属性不匹配的 JSON 数据的其余部分?