代码之家  ›  专栏  ›  技术社区  ›  mikro098

使用Decodable保存领域中的对象数组

  •  1
  • mikro098  · 技术社区  · 7 年前

    我有一个符合可解码协议(从API获取数据)的类,我想将其保存在领域数据库中。当我的属性之一是array(List)时出现问题。上面写着 Cannot automatically synthesize Decodable because List<Item> does not conform to Decodable 绕过此问题的最佳方法是什么?领域仅支持基元类型的数组。

    这是我的班级:

    class PartValue: Object, Decodable {
        @objc dynamic var idetifier: Int = 0
        let items = List<Item>()
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Dávid Pásztor    7 年前

    使用Swift 4.1中实现的期待已久的条件符合性,您可以简单地声明 List 符合 Decodable 如果其 Element 符合 可解码的

    extension List: Decodable where List.Element: Decodable {
        public convenience init(from decoder: Decoder) throws {
            self.init()
            var container = try decoder.unkeyedContainer()
            let array = try container.decode(Array<Element>.self)
            self.append(objectsIn: array)
        }
    }
    

    为了使这项工作适用于您的具体案例,您需要确保 Item 也符合 可解码的

    如果您还需要 Encodable 一致性,只需扩展 列表 也支持这一点。

    extension List: Encodable where List.Element: Encodable {
        public func encode(to encoder: Encoder) throws {
            var container = encoder.unkeyedContainer()
            try container.encode(contentsOf: Array(self))
        }
    }
    
        2
  •  1
  •   Bibek    6 年前

    迪维德的解决方案对我并不完全有效。我不得不通过替换 decoder.unkeyedContainer() decoder.singleValueContainer() ,下面是解决方案。

    extension List: Decodable where List.Element: Decodable {
        public convenience init(from decoder: Decoder) throws {
            self.init()
            let container = try decoder.singleValueContainer()
            let array = try container.decode([Element].self)
            self.append(objectsIn: array)
        }
    }