gpt4 book ai didi

json - Swift - 将类型动态传递给 JSONDecoder

转载 作者:行者123 更新时间:2023-11-28 14:25:57 25 4
gpt4 key购买 nike

我正在尝试使用通用嵌套对象从 json 对象解码,为此我想在解码时动态传递类的类型。

例如,我的类是扩展了 ObjectModel(和 :Codable)的 EContactModel 和 ENotificationModel。 ENotificationModel 可以包含嵌套的 ObjectModel(可以是联系人、通知或其他对象模型)。

我有这样一个类型的字典:

static let OBJECT_STRING_CLASS_MAP = [
"EContactModel" : EContactModel.self,
"ENotificationModel" : ENotificationModel.self
...
]

我在 ENotificationModel 中的解码初始化方法如下所示:

required init(from decoder: Decoder) throws
{
try super.init(from: decoder)
let values = try decoder.container(keyedBy: CodingKeys.self)


...
//decode some fields here
self.message = try values.decodeIfPresent(String.self, forKey: .message)
...

//decode field "masterObject" of generic type ObjectModel
let cls = ObjectModelTypes.OBJECT_STRING_CLASS_MAP[classNameString]!
let t = type(of: cls)
print(cls) //this prints "EContactModel"
self.masterObject = try values.decodeIfPresent(cls, forKey: .masterObject)
print(t) //prints ObjectModel.Type
print(type(of: self.masterObject!)) //prints ObjectModel

}

我也尝试传递 type(of: anObjectInstanceFromADictionary) 但仍然无法正常工作,但如果我传递 type(of: EContactModel()) 它会起作用。我无法理解这一点,因为两个对象是相同的(即 EContactModel 的实例)

有解决办法吗?

最佳答案

您可以使用可选变量声明您的对象模型,然后让 JSONDecoder 为您解决。

class ApiModelImage: Decodable {
let file: String
let thumbnail_file: String
...
}

class ApiModelVideo: Decodable {
let thumbnail: URL
let duration: String?
let youtube_id: String
let youtube_url: URL
...
}

class ApiModelMessage: Decodable {
let title: String
let body: String
let image: ApiModelImage?
let video: ApiModelVideo?
...
}

那么你所要做的就是......

if let message = try? JSONDecoder().decode(ApiModelMessage.self, from: data) {
if let image = message.image {
print("yay, my message contains an image!")
}
if let video = message.video {
print("yay, my message contains a video!")
}
}

或者,您可以使用泛型并在调用 API 代码时指定类型:

func get<T: Decodable>(from endpoint: String, onError: @escaping(_: Error?) -> Void, onSuccess: @escaping (_: T) -> Void) {
getData(from: endpoint, onError: onError) { (data) in
do {
let response = try JSONDecoder().decode(T.self, from: data)
onSuccess(response)
} catch {
onError(error)
}
}
}

以这种方式使用,您只需确保定义了预期的响应类型:

    let successCb = { (_ response: GetUnreadCountsResponse) in
...
}
ApiRequest().get(from: endpoint, onError: { (_) in
...
}, onSuccess: successCb)

由于您将 successCb 定义为需要 GetUnreadCountsResponse 模型,因此 API get 方法泛型在运行时将是 GetUnreadCountsResponse 类型。

祝你好运!

关于json - Swift - 将类型动态传递给 JSONDecoder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51557163/

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