编辑:作为Rob Napier wrote,Xcode 9.2中存在问题。在Xcode 9.3中,问题已不再适用。
我的服务器json响应全部打包在data
对象中:
{
"data": {...}
}
所以我有以下泛型类型来解析JSON:
class DataContainer<T: Decodable>: Decodable {
let data: T
init(data: T)
self.data = data
}
}
大部分时间它工作正常,但有一个响应,我还需要解析included
字段,所以我创建了SpecificDataContainer
子类:
class SpecificDataContainer: DataContainer<DataObject> {
let included: [IncludedObject]
init() {
included = []
super.init(data: DataObject(id: ""))
}
}
上面的实现给了我编译器错误'required' initializer 'init(from:)' must be provided by subclass of 'DataContainer'
。
我在init(from:)
中实现了SpecificDataContainer
,但编译器仍然给出了同样的错误。
我似乎错过了一些明显的东西。我究竟做错了什么?这是我的完整代码:
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<T: Decodable>: Decodable {
let data: T
init(data: T) {
self.data = data
}
}
class SpecificDataContainer: DataContainer<DataObject> {
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!")
}
答案 0 :(得分:2)
由于某些原因,Xcode无法识别init(from:)
子类中自动生成的Codable
(因为Rob说它可能是一个错误)。在Xcode 9.3发布之前,您可以通过将初始化程序添加到基类来解决此问题:
class DataContainer<T: Decodable>: 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)
}
答案 1 :(得分:0)
这似乎是Xcode 9.2中的一个错误。在9.3b4你的代码很好。