gpt4 book ai didi

ios - 子类化 swift 通用可解码类型

转载 作者:可可西里 更新时间:2023-11-01 01:09:06 25 4
gpt4 key购买 nike

编辑:作为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'

我在 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<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!")
}

最佳答案

出于某种原因,Xcode 无法识别 Codable 子类中自动生成的 init(from:)(正如 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)
}

关于ios - 子类化 swift 通用可解码类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49540520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com