【问题标题】:Trying to make a class codable in Swift but it is not the correct format?试图在 Swift 中编写一个可编码的类,但格式不正确?
【发布时间】:2019-08-14 14:36:08
【问题描述】:

我正在创建一个符合可编码的类。

我有这个:

import Foundation

class Attribute : Decodable {

  var number: Int16
  var label: String?
  var comments: String?

  init(number:Int16, label:String?, comments:String?) {
    self.number = number
    self.label = label
    self.comments = comments
  }

  // Everything from here on is generated for you by the compiler
  required init(from decoder: Decoder) throws {
    let keyedContainer = try decoder.container(keyedBy: CodingKeys.self)
    number = try keyedContainer.decode(Int16.self, forKey: .number)
    label = try keyedContainer.decode(String.self, forKey: .label)
    comments = try keyedContainer.decode(String.self, forKey: .comments)
  }

  enum CodingKeys: String, CodingKey {
    case number
    case label
    case comments
  }

}

extension Attribute: Encodable {

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(number, forKey: .number)
    try container.encode(label, forKey: .label)
    try container.encode(comments, forKey: .comments)
  }
}

这显然很好。

我创建了一个Attribute 的实例并使用以下代码对其进行编码:

  let newAttribute = Attribute.init(number:value.number, label:value.label, comments:value.shortcut)

然后我创建一个包含这些属性的数组并使用

对该数组进行编码
  let array = try JSONEncoder().encode(array)

这会将Attribute 的数组编码为Data。

然后我尝试使用以下方法将Data 对象转换回Attribute 的数组:

let array = try JSONDecoder().decode(Attribute.self, from: data) as! Array<Attribute> 

我得到的第一个错误是:

从“属性”转换为不相关类型“数组”总是失败

如果我移除铸件,我会在解码尝试时发现此错误...

可选(“数据格式不正确。”)

有什么想法吗?

【问题讨论】:

  • 而不是 error.localizedDescription 仅打印 error。它准确地告诉你出了什么问题

标签: swift swift4 codable decodable encodable


【解决方案1】:

你需要传入数组进行解码,不要传入数组元素类型,然后尝试将其强制转换为数组,这没有任何意义。 YourType 和Array&lt;YourType&gt; 是两种完全不同且完全不相关的类型,因此不能将一个转换为另一个,调用JSONDecoder.decode(_:from:) 时需要使用特定的类型。

let array = try JSONDecoder().decode([Attribute].self, from: data)

顺便说一句,正如您在上一个问题中已经指出的那样,无需手动编写 init(from:) 和 encode(to:) 方法或 CodingKeys enum 因为对于您的简单类型,编译器可以自动合成所有那些给你的。此外,如果您使用 struct 而不是 class,您还可以免费获得成员明智的初始化程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-04
    • 2018-09-01
    • 2019-07-04
    • 2018-07-29
    • 1970-01-01
    • 2018-02-28
    相关资源
    最近更新 更多