简体   繁体   中英

Realm - list of objects in an object (Swift 3)

I have a Models class defined like this:

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

And I would like to use it something like this:

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

So basically the idea is to just pass the whole JSON to the initial RecipeModel class, and it should parse it out and create the objects I need in the Realm database. It works quite well except for the nested list of IngredientsModel . They do not get added to the realm database.

在此处输入图片说明

在此处输入图片说明

What I see as a potential problem is that I call self.init() before I call self.data in the convenience init , but I do not see any way to work around this. Do you guys please know how I could achieve that also the IngredientsModel would have its contents set up properly and I would have a list of ingredients in the RecipeModel ?

Your current implementation doesn't work, because you are not calling the getter/setter of ingredients in the init method of RecipeModel and hence the IngredientsModel instances are never persisted in Realm.

Moreover, using a computed property as a one-to-many relationship (Realm List) is a really bad idea, especially if you are parsing the results inside the getter for this property. Every time you call the getter of ingredients , you create new model objects instead of just accessing the existing ones that are already stored in Realm, but you are never deleting the old ones. If you were actually saving the IngredientsModel instances to Realm (which you don't do at the moment as mentioned above) you would see that your database is full of duplicate entries.

Your whole approach seems really suboptimal. You shouldn't store the unparsed data object in your model class and use computed properties to parse it. You should parse it when initializing your models and shouldn't store the unparsed data at all. You can use the ObjectMapper library for creating Realm objects straight away from the JSON response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM