简体   繁体   English

解码具有不同类型的Json对象

[英]Decode Json object that has different types

I have a Json data which I use to populate Table Views. 我有一个用于填充表视图的Json数据。 Json has one two type of object in its main part which are "Main" and n-number tableview object; Json在主体部分有两种类型的对象:“ Main”和n值tableview对象;

Main object has two string type in it ("url" and "bar_name"). 主对象中有两种字符串类型(“ url”和“ bar_name”)。 Tableview objects has 3 type in it ("name", "id", [tableData]). Tableview对象具有3种类型(“名称”,“ id”,[tableData])。 This is common for all tableview objects (n number). 这对于所有tableview对象(n个数字)都是通用的。 Tabledata object which populate cells has 3 different type because one opens a url, other one opens a new table and last one just do an action. 填充单元格的Tabledata对象具有3种不同的类型,因为一个打开一个url,另一个打开一个新表,最后一个只是执行一个操作。

I want to decode this type of json to structures. 我想将这种json解码为结构。 Is it possible? 可能吗?

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

在此处输入图片说明

EDIT: I found a similar post but doesn't work for my situation. 编辑:我发现了类似的职位,但不适用于我的情况。 I'm getting below error 我遇到错误了

Type ' table' does not conform to protocol 'Encodable' 类型“表格”不符合协议“可编码”

Swift JSONDecoder with multiple structures 具有多种结构的Swift JSONDecoder

EDIT2: I added code for decoding but I'm getting nil for both mainPage and User. EDIT2:我添加了用于解码的代码,但mainPage和User都为零。 What am I missing with my structure? 我的结构缺少什么?

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

You should implement custom initializer for Decoding and encode(to encoder: Encoder) for Encoding. 您应该实现用于解码的自定义初始化程序,并实现用于encode(to encoder: Encoder) Try this one: 试试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM