【问题标题】:Codable Data Model - self used before all stored properties are initialized可编码数据模型 - 在所有存储属性初始化之前自行使用
【发布时间】:2018-09-09 04:27:26
【问题描述】:

我正在尝试为正在获取(和发送)到服务器的 Codable JSON 数据创建数据模型。我的两个问题是

  1. 如何设计模型,以便创建新模型对象、设置属性并将其发送到服务器?

  2. 如何设计带有不会出现上述错误的编码器初始化的模型?

这是我的一个模型的外观示例:

struct TestRailSection : Codable
{
    let id:Int
    let suiteID:Int
    let parentID:Int
    let depth:Int
    let displayOrder:Int
    let name:String
    let description:String

    enum CodingKeys : String, CodingKey
    {
        case id           = "id"
        case suiteID      = "suite_id"
        case parentID     = "parent_id"
        case displayOrder = "display_order"
        case depth        = "depth"
        case name         = "name"
        case description  = "description"
    }

    init(name:String, description:String)
    {
        id = 0
        suiteID = 0
        parentID = 0
        depth = 0
        displayOrder = 0
        self.name = name
        self.description = description
    }

    init(from decoder:Decoder) throws
    {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        do { id           = try values.decode(Int.self,    forKey: .id) }           catch { id = 0 }
        do { suiteID      = try values.decode(Int.self,    forKey: .suiteID) }      catch { suiteID = 0 }
        do { parentID     = try values.decode(Int.self,    forKey: .parentID) }     catch { parentID = 0 }
        do { depth        = try values.decode(Int.self,    forKey: .depth) }        catch { depth = 0}
        do { displayOrder = try values.decode(Int.self,    forKey: .displayOrder) } catch { displayOrder = 0 }
        do { name         = try values.decode(String.self, forKey: .name) }         catch { name = ""}
        do { description  = try values.decode(String.self, forKey: .description) }  catch { description = "" }
    }

    init(to encoder:Encoder) throws
    {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(suiteID, forKey: .suiteID)
        try container.encode(parentID, forKey: .parentID)
        try container.encode(depth, forKey: .depth)
        try container.encode(displayOrder, forKey: .displayOrder)
        try container.encode(name, forKey: .name)
        try container.encode(description, forKey: .description)
    }
}

我可以通过这个成功地从服务器获取数据,但是如何创建一个编码模型?额外的init(没有en/decoder的那个)是必要的吗?可以以更好的方式完成吗?上面的错误抱怨属性没有在编码器初始化中初始化。

【问题讨论】:

  • 您收到此错误是因为您实现了错误的初始化程序init(to encoder:Encoder)。没有这样的。为了能够符合Encodable协议,你需要实现func encode(to encoder: Encoder) throws { ... }。我建议你阅读Encoding and Decoding Custom Types
  • 谢谢!这解决了它。如果您创建一个正确的答案,我会接受它。
  • 好吧,我刚刚对答案发表了评论????

标签: json swift codable


【解决方案1】:

CodableEncodableDecodable 协议组成。要符合Codable 协议,您需要实现所需的方法和初始化程序。要满足您需要实现的Codable 要求:


在您的情况下,您正在实施 错误 要求以满足CodableCodable 要求中不存在像 init(to encoder:Encoder) 这样的东西。相反,您可能会实现encode(to:)-

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(id, forKey: .id)
    try container.encode(suiteID, forKey: .suiteID)
    try container.encode(parentID, forKey: .parentID)
    try container.encode(depth, forKey: .depth)
    try container.encode(displayOrder, forKey: .displayOrder)
    try container.encode(name, forKey: .name)
    try container.encode(description, forKey: .description)
}

要了解更多,你应该看看Encoding and Decoding Custom Types

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 2023-01-12
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    相关资源
    最近更新 更多