子类化swift通用可解码类型

编辑:正如Rob Napier所写 ,问题存在于Xcode 9.2中。 在Xcode 9.3中,问题已不再适用。

我的服务器json响应全部打包在data对象中:

 { "data": {...} } 

所以我有以下generics类型来解析JSON:

 class DataContainer: Decodable { let data: T init(data: T) self.data = data } } 

大部分时间它工作正常,但有一个响应,我还需要解析included字段,所以我创建了SpecificDataContainer子类:

 class SpecificDataContainer: DataContainer { let included: [IncludedObject] init() { included = [] super.init(data: DataObject(id: "")) } } 

上面的实现给我编译错误'required' initializer 'init(from:)' must be provided by subclass of 'DataContainer'

我在SpecificDataContainer实现了init(from:) ,但编译器仍然给出了同样的错误。

我似乎错过了一些明显的东西。 我究竟做错了什么? 这是我的完整代码:

 import Foundation let jsonData = """ { "data": { "id": "some_id" }, "included": [ { "id": "some_id2" } ] } """.data(using:.utf8)! struct DataObject: Decodable { let id: String } struct IncludedObject: Decodable { let id: String } class DataContainer: Decodable { let data: T init(data: T) { self.data = data } } class SpecificDataContainer: DataContainer { let included: [IncludedObject] init() { included = [] super.init(data: DataObject(id: "")) } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) var includedArray = try container.nestedUnkeyedContainer(forKey: .included) var includedObjects:[IncludedObject] = [] while !includedArray.isAtEnd { let includedObject = try includedArray.decode(IncludedObject.self) includedObjects.append(includedObject) } self.included = includedObjects try super.init(from: decoder) } private enum CodingKeys: String, CodingKey { case data = "data" case included = "included" } } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 if let obj = try? decoder.decode(SpecificDataContainer.self, from: jsonData) { print("object id \(obj.data.id)") } else { print("Fail!") } 

出于某种原因,Xcode无法识别Codable子类中的自动生成的init(from:) (因为Rob说它可能是一个bug)。 在Xcode 9.3发布之前,您可以通过向基类添加初始化程序来解决此问题:

 class DataContainer: Decodable { let data: T enum CodingKeys: String, CodingKey { case data } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) data = try container.decode(T.self, forKey: .data) } 

这似乎是Xcode 9.2中的一个错误。 在9.3b4你的代码很好。