将通用可编码类型作为参数传递给保存到领域的方法 [英] Pass A Generic Codable Type as Parameter to a Method for Saving to Realm
问题描述
我正在尝试创建用于解码某些JSON数据的通用方法。我需要将JSON数据转换为对象,以便以后保存在Realm中。
I am trying to create a generic method for decoding some JSON data. I need to cast the JSON data into Objects for later saving in Realm.
例如:获取车辆的品牌,型号,颜色和车身类型。
For example: Getting the makes, models, colors, and body types of vehicles.
在我的每个JSON调用中,结果的格式都完全相同(请参阅问题末尾的结构)。为简便起见,我仅向您显示品牌和型号,但是颜色和主体类型完全相同,只是名称有所更改。
In each of my JSON calls to the results are formatted exactly the same (See my structs at the end of the question). For brevity, I am only showing you Makes and Models, but Colors and Body Types are exactly the same, just with the name changes.
我目前有四种方法调用,其中 Makes.self
被其他结构之一替换。
I currently have four methods that I call where Makes.self
is replaced with one of the other structs.
if let results = try? JSONDecoder().decode(Makes.self, from: jsonData)) {
DispatchQueue.main.async {
//save data to realm
self?.save(objects: results.data )
}
}
一旦获得JSON数据,我想将数据发送到通用方法进行处理。
Once I get my JSON Data, I would like to send my data to a generic method for processing.
所以我可以调用类似这样的东西:
So I could call something like :
process(jsonData, modelType: Makes.self)
process(jsonData, modelType: Models.self)
process(jsonData, modelType: Colors.self)
process(jsonData, modelType: Bodies.self)
我已经尝试过泛型类型的变体,但是我不能
I have tried variations on generic types but I can't seem to get it right.
func process<T:Codable>(_ jsonData: Data, modelType: T.Type = T.self) {
if let results = try? JSONDecoder().decode(modelType.self, from: jsonData) {
DispatchQueue.main.async {
//save data to realm
self?.save(objects:results.data)
}
}
}
我如何通过通用的可解码协议类型?
做出
import RealmSwift
struct Makes: Codable {
let result: String
let data: [Make]
enum CodingKeys: String, CodingKey {
case result = "Result"
case data = "Data"
}
}
class Make: Object, Codable {
@objc dynamic var key: String
@objc dynamic var value: String
@objc dynamic var shortCode: String
@objc dynamic var active: Bool
enum CodingKeys: String, CodingKey {
case key = "Key"
case value = "Value"
case shortCode = "ShortCode"
case active = "Active"
}
}
模型
import RealmSwift
struct Makes: Codable {
let result: String
let data: [Make]
enum CodingKeys: String, CodingKey {
case result = "Result"
case data = "Data"
}
}
class Make: Object, Codable {
@objc dynamic var key: String
@objc dynamic var value: String
@objc dynamic var shortCode: String
@objc dynamic var active: Bool
enum CodingKeys: String, CodingKey {
case key = "Key"
case value = "Value"
case shortCode = "ShortCode"
case active = "Active"
}
}
推荐答案
为什么您希望任何 Codable
类型具有 data
属性? results.data
无法工作...您需要使 T
成为 Object
可以将其保存到 Realm
以及 Decodable
以便将其传递给 decode
方法。
Why would you expect any Codable
type to have a data
property? results.data
cannot work... You need to make T
a subclass of Object
to be able to save it to Realm
and also Decodable
to be able to pass it to the decode
method.
func process<T:Object>(_ jsonData: Data, modelType: T.Type) where T:Decodable {
if let results = try? JSONDecoder().decode(modelType.self, from: jsonData) {
DispatchQueue.main.async {
//save data to realm
self?.save(objects:results)
}
}
}
这篇关于将通用可编码类型作为参数传递给保存到领域的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!