解码具有不同类型的

时间:2017-12-22 10:37:32

标签: ios json swift decode codable

我有一个Json数据,用于填充表视图。 Json在其主要部分中有两种类型的对象,即" Main"和n-number tableview对象;

主对象中有两个字符串类型(" url"" bar_name")。 Tableview对象中有3种类型(" name"," id",[tableData])。这对于所有tableview对象(n number)都很常见。填充单元格的Tabledata对象有3种不同的类型,因为一个打开一个URL,另一个打开一个新表,最后一个只是执行操作。

我想将这种类型的json解码为结构。有可能吗?

    //For All Types
protocol commonCellTypes: Codable{
    var type: Int { get }

}
struct User: Codable{
    let mainPage: MainPage?
    let tables: [table]?
}
struct MainPage: Codable{
    let url: String?
    let bar_name: String?
}
struct table: Codable{
    let name: String?
    let id: String?
    let Cells: [commonCellTypes]

    enum CodeKeys: CodingKey
    {
        case name
        case id
        case tableDatas
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodeKeys.self)
        name = try container.decode (String.self, forKey: .name)
        id = try container.decode (String.self, forKey: .id)
        Cells = try container.decode ([commonCellTypes].self, forKey: .tableDatas)
    }

    func encode(to encoder: Encoder) throws
    {
        var container = encoder.container(keyedBy: CodeKeys.self)
        try container.encode (name, forKey: .name)
        try container.encode (id, forKey: .id)
        try container.encode (Cells, forKey: .tableDatas)
    }
}
//Type 2
struct cellType2: commonCellTypes{
    let cellText: String
    let imageName: String?
    let url: URL?
    let type: Int
}
//Type 1
struct cellType1: commonCellTypes{
    let cellText: String
    let imageName: String
    let table_id: String
    let type: Int
}
//Type 0
struct cellType0: commonCellTypes{
    let cellText: String
    let imageName: String
    let type: Int
    let action: String
}

enter image description here

编辑:我找到了类似的帖子,但对我的情况不起作用。我收到了以下错误

  

键入'表'不符合协议' Encodable'

Swift JSONDecoder with multiple structures

EDIT2:我添加了解码代码,但我对主页和用户都是nil。我的结构缺少什么?

  let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
            let decoder = JSONDecoder()
            let admin = try! decoder.decode(User.self, from: data)
            print(admin)

1 个答案:

答案 0 :(得分:0)

您应该为解码实现自定义初始值设定项,并为编码实现encode(to encoder: Encoder)。试试这个:

//For All Types
protocol commonCellTypes: Codable{

}
struct MainStruct: Codable{
    let tables: [table]
}
struct table: Codable{
    let name: String?
    let id: String?
    let tableDatas: [commonCellTypes]

    enum CodeKeys: CodingKey
    {
    case name
    case id
    case tableDatas
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodeKeys.self)
        name = try container.decode (String.self, forKey: .name)
        id = try container.decode (String.self, forKey: .id)
        tableDatas = try container.decode ([commonCellTypes].self, forKey: .tableDatas)
    }

    func encode(to encoder: Encoder) throws
    {
        var container = encoder.container(keyedBy: CodeKeys.self)
        try container.encode (name, forKey: .name)
        try container.encode (id, forKey: .id)
        try container.encode (tableDatas, forKey: .tableDatas)
    }
}
//Type 2
struct cellType2: commonCellTypes{
    let cellText: String
    let imageName: String?
    let url: URL?
    let type: Int
}
//Type 1
struct cellType1: commonCellTypes{
    let cellText: String
    let imageName: String
    let table_id: String
    let type: Int
}
//Type 0
struct cellType0: commonCellTypes{
    let cellText: String
    let imageName: String
    let type: Int
    let action: String
}