将通用可编码类型作为参数传递给保存到领域的方法 [英] Pass A Generic Codable Type as Parameter to a Method for Saving to Realm

查看:86
本文介绍了将通用可编码类型作为参数传递给保存到领域的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建用于解码某些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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆