Объедините класс Realm и Codable в Swift 4 - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь убить двух зайцев одним классом.

Я хочу использовать некоторые данные JSON и сохранить их в базе данных Realm.

Вот мои данные JSON

{ "Colors": 
    [   {"Name" : "Blue"},
        {"Name" : "Red"},
        {"Name" : "Green"},
        {"Name" : "Black"}
    ]
}

У меня уже есть класс Realm, который отлично работает.

class Color : Object {
    //RealmObject
    @objc dynamic var name  : String = ""
}

И когда я его использую

import SwiftyJSON
import RealmSwift

func process(jsonData: JSON) {
    for color in jsonData.arrayValue {
        let c = Color()
        c.name = color["Name"]
        save(data: c)
    }
}

func save(data: Object){
        do{
            try realm.write {
                realm.add(data)
            }

        } catch {
            print("Error saving data: \(error)")
        }
}

Затем я обновил свой, я обновил свой класс Color, чтобы соответствоватьCodable

class Color : Object, Codable {
    //RealmObject
    @objc dynamic var name  : String = ""

    //Codable For JSON Deserialziation
    enum CodingKeys: String, CodingKey {
        case name = "Name"
    }

}

struct Colors: Codable {
    let colors: [Color]

    enum CodingKeys: String, CodingKey {
        case colors = "Colors"
    }
}

Что бы я хотел сделать, чтобы сделать кодирование jsonData и сохранение его в Realm.

if let colors = try? JSONDecoder().decode(Colors.self, from: data.rawData()) {
   self.save(data: colors)
}

Но я не могу заставить его работать.Я пробовал несколько способов получить ошибку:

Невозможно преобразовать значение типа 'Цвета?'к ожидаемому типу аргумента «Объект»

Или попытка for цветов

Тип «Цвета» не соответствует протоколу «Последовательность»

Возможно ли это сделать?

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Проблема в том, что colors имеет тип Colors, который не является подклассом Object, но имеет свойство типа [Color].Вам нужно либо выполнить итерацию по свойству и сохранить каждый объект индивидуально, либо, что еще лучше, перегрузить save для обработки массива Object экземпляров подкласса.

func save<T:Object>(objects: [T]){
    do{
        try realm.write {
            realm.add(objects)
        }
    } catch {
        print("Error saving data: \(error)")
    }
}

Затем сохранить объекты:

if let colors = try? JSONDecoder().decode(Colors.self, from: data.rawData()) {
   self.save(objects: colors.colors)
}
0 голосов
/ 10 октября 2018

Замените

self.save(data: colors)

на

colors.colors.forEach { self.save(data:$0) }

как colors здесь

if let colors = try? JSONDecoder().decode(Colors.self, from: data.rawData()) {---}

- это объект, который содержит свойство массива colors изтип Color

...