EDIT : Comme Rob Napier a écrit , le problème existe dans Xcode 9.2. Dans Xcode 9.3 le problème n'est plus pertinent.
Les réponses json de mon serveur sont toutes emballées dans data
objet :
{
"data": {...}
}
J'ai donc le type générique suivant pour analyser le JSON :
class DataContainer<T: Decodable>: Decodable {
let data: T
init(data: T)
self.data = data
}
}
La plupart du temps, cela fonctionne bien, mais il y a une réponse pour laquelle je dois également analyser les données suivantes included
J'ai donc créé un champ SpecificDataContainer
sous-classe :
class SpecificDataContainer: DataContainer<DataObject> {
let included: [IncludedObject]
init() {
included = []
super.init(data: DataObject(id: ""))
}
}
L'implémentation ci-dessus me donne une erreur de compilation 'required' initializer 'init(from:)' must be provided by subclass of 'DataContainer'
.
J'ai mis en place init(from:)
en el SpecificDataContainer
mais le compilateur me donne toujours la même erreur.
Il semble que je manque quelque chose d'évident ici. Qu'est-ce que je fais de mal ? Voici mon code complet :
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!")
}