使用任何类型的Codable对象创建Codable对象?

时间:2018-01-05 14:43:16

标签: swift codable

我希望创建一个类,它将存储Date以及符合Codable协议的任何对象。我希望这个类也符合Codable协议本身。

我可以按如下方式为一个对象执行此操作:

class CodableContainerA: NSObject, Codable {
    var date: Date?
    var item: CodableTypeA?
}

我宁愿不必为我拥有的每个CodableTypeX创建一个单独的CodableContainerX。

我目前的解决方法是创建一个符合CodableBaseClass的名为Codable的类,从中派生每个CodableType并按如下方式定义我的类:

class CodableContainer: NSObject, Codable {
    var date: Date?
    var item: CodableBaseClass?
}

这似乎还有很长的路要走,感觉就像我应该通过使CodableType符合协议而做的事情,但我不确定如何。如果我将item定义为Codable?(Any & Codable)?类型,则会收到错误消息

Type 'CodableContainer' does not conform to protocol 'Decodable'

我正在使用Swift 4。

任何帮助或建议都将被感激地接受。非常感谢,

2 个答案:

答案 0 :(得分:4)

每当您发现自己想知道每种基础类型的单独类时,请考虑"generics"。例如。

struct CodableContainer<T: Codable>: Codable { 
    let date: Date
    let item: T
}
  • 除非您出于某些特定原因需要struct,否则我将class使用NSObject
  • 除非你出于某种原因需要它们,否则我会使属性不可变。
  • 除非有特定原因要求此特定容器需要NSObject子类,否则我不会对DateDecodingStrategy进行子类化。
  • 除非您绝对需要它们是可选的,否则我会将属性设置为非可选属性。

但是你可以根据需要编辑它。关键点是generic模式。

您可能需要使用某些一致的extension CodableContainer { static func decodeJSON(_ data: Data) throws -> CodableContainer { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 return try decoder.decode(self, from: data) } } 解码的解码功能,例如

dateDecodingStrategy

显然,使用你想要的任何let result = try CodableContainer<Foo>.decodeJSON(data) 。但是你可以解码:

int checkedRowCount = 0;
Parallel.ForEach(
    dataGridView1.Rows.Cast<DataGridViewRow>()
    , row =>
    {
        DataGridViewCell cell = row.Cells[6];

        if (!(cell.Value is DBNull))
        {
            if (Convert.ToBoolean(cell.Value))
            {
                checkedRowCount++;

                for (int i = 0; i < dataGridView1.Columns.Count - 1; i++)
                {
                    // Works on The other column value    
                    // Add the value to excel here   
                }

                // Add to the ListBox only once per Row, Instead of Once per Column per Row
                listBox1.BeginInvoke((Action)(() =>
                {
                    listBox1.Items.Add(checkedRowCount);
                }));
            }
        }
    });

答案 1 :(得分:3)

这是泛型类的用途:

class CodableContainer<T: Codable>: NSObject, Codable {
    var date: Date?
    var item: T?
}