WedX - журнал о программировании и компьютерных науках

Realm — список объектов в объекте (Swift 3)

У меня есть класс моделей, определенный следующим образом:

class BaseModel: Object {
    var data: JSON = JSON.null

    convenience init(_ data: JSON) {
        self.init()
        self.data = data
    }

    override static func ignoredProperties() -> [String] {
        return ["data"]
    }
}

class RecipeModel: BaseModel {
    dynamic var title: String {
        get { return data["fields"]["title"].stringValue }
        set { self.title = newValue }
    }

    ... more vars ...

    var ingredients: List<IngredientsModel> {
        get {
            let ingredients = List<IngredientsModel>()

            for item in data["fields"]["ingredients"] {
                ingredients.append(IngredientsModel(item.1))
            }

            return ingredients
        }
        set { self.ingredients = newValue }
    }
}

class IngredientsModel: BaseModel {
    dynamic var text: String {
        get { return data["text"].stringValue }
        set { self.text = newValue }
    }

    ... more vars ...
}

И я хотел бы использовать его примерно так:

Api.shared.fetchAllEntries().call(onSuccess: {response in
        print(response.json)

        let realm = try! Realm()
        try! realm.write {
            realm.deleteAll()
        }

        for item in response.json["items"].arrayValue {
            let recipe = RecipeModel(item)
            try! realm.write {
                realm.add(recipe)
            }
        }
    }, onError: {
        print("error")
    })

Итак, в основном идея состоит в том, чтобы просто передать весь JSON начальному классу RecipeModel, и он должен разобрать его и создать нужные мне объекты в базе данных Realm. Он работает довольно хорошо, за исключением вложенного списка IngredientsModel. Они не добавляются в базу данных области.

введите здесь описание изображения

введите здесь описание изображения

Что я вижу как потенциальную проблему, так это то, что я вызываю self.init() до вызова self.data в convenience init, но я не вижу никакого способа обойти это. Ребята, подскажите, пожалуйста, как мне добиться того, чтобы в IngredientsModel было правильно настроено содержимое, и у меня был список ингредиентов в RecipeModel?

04.09.2017

  • Если вы хотите, чтобы у вас было List в базе данных, это должно быть let ingredients: List<IngredientsModel> без каких-либо пользовательских геттеров/сеттеров. 04.09.2017
  • @user28434 user28434 Спасибо за ваш ответ - да, это, вероятно, сработает, но тогда я не смогу установить содержимое списка непосредственно в самой переменной, а где-то в контроллере представления, добавляя объекты к объекту RecipeModel, что кажется немного странно для меня. Неужели нет возможности использовать собственный геттер для переменной списка? 04.09.2017

Ответы:


1

Ваша текущая реализация не работает, потому что вы не вызываете геттер/сеттер ingredients в методе init RecipeModel и, следовательно, экземпляры IngredientsModel никогда не сохраняются в Realm.

Более того, использование вычисляемого свойства в качестве отношения «один ко многим» (Realm List) — действительно плохая идея, особенно если вы анализируете результаты внутри геттера для этого свойства. Каждый раз, когда вы вызываете геттер ingredients, вы создаете новые объекты модели, а не просто получаете доступ к существующим, которые уже хранятся в Realm, но вы никогда не удаляете старые. Если бы вы на самом деле сохраняли экземпляры IngredientsModel в Realm (чего вы не делаете в данный момент, как упоминалось выше), вы бы увидели, что ваша база данных полна повторяющихся записей.

Весь ваш подход кажется действительно неоптимальным. Вы не должны хранить не проанализированный объект data в своем классе модели и использовать вычисляемые свойства для его анализа. Вы должны анализировать его при инициализации своих моделей и вообще не должны хранить неанализированные данные. Вы можете использовать библиотеку ObjectMapper для создания объектов Realm прямо из JSON. отклик.

04.09.2017
  • Имеет смысл, спасибо, я попробую ObjectMapper и посмотрю, что из этого получится. 04.09.2017
  • Не беспокойтесь, рад, что смог помочь. 04.09.2017
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]