Передайте универсальный кодируемый тип в качестве параметра методу сохранения в царство - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь создать универсальный метод для декодирования некоторых данных JSON. Мне нужно преобразовать данные JSON в объекты для последующего сохранения в Realm.

Например: получение марок, моделей, цветов и типов кузова транспортных средств.

В каждом из моих JSON-вызовов результаты форматируются одинаково (см. Мои структуры в конце вопроса). Для краткости я показываю вам только модели и модели, но цвета и типы кузова совпадают, только с изменением названия.

В настоящее время у меня есть четыре метода, которые я вызываю, где Makes.self заменяется одной из других структур.

if let results = try? JSONDecoder().decode(Makes.self, from: jsonData)) {
        DispatchQueue.main.async {
        //save data to realm
        self?.save(objects: results.data )
    }
}

Как только я получу свои данные JSON, я хотел бы отправить свои данные в общий метод для обработки.

Так что я мог бы назвать что-то вроде:

process(jsonData, modelType: Makes.self)
process(jsonData, modelType: Models.self)
process(jsonData, modelType: Colors.self)
process(jsonData, modelType: Bodies.self)

Я пробовал варианты на универсальных типах, но не могу понять, как это правильно.

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"
    }
}

1 Ответ

0 голосов
/ 06 ноября 2018

Почему вы ожидаете, что любой тип Codable будет иметь свойство data? results.data не может работать ... Вам нужно сделать T подклассом Object, чтобы иметь возможность сохранить его в Realm, а также Decodable, чтобы можно было передать его в метод decode.

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)
        }
    }
}
...