mardi 5 avril 2016

Dynamically mirror properties to another class

I'm currently working on using Realm together with the Swift framework Oatmeal. Now, both of those require model classes (Oatmeal can do automatic serialisation). My structure for a given Oatmeal model and Realm model are as follows:

class OatmealModel: SerializableObject {
    var id: Int = 0
    var someOtherProperty: String?
    var anotherUnknownProperty: SomeType?

    var store: RealmModel?
}

class RealmModel: Object {
    dynamic var id: Int = 0
    dynamic var someOtherProperty: String?
    dynamic var anotherUnknownProperty: SomeType?

    override static func primaryKey() -> String? {
        return "id"
    }
}

As should be clear, they both hold the same properties, but the OatmealModel is always the one I interact with. Aside from this, the OatmealModel also implements a protocol to retrieve data:

protocol PersistentStore {
    func save()

    func findStore()

    func all() -> [PersistentStore]

    func filter(predicate: NSPredicate) -> [PersistentStore]
}

These methods allow us to fetch from the Realm database and then hydrate the oatmeal model, and get only oatmeal models back. And then calling save will write back to realm.

So essentially, what I want to do is:

  • When retrieving entities from the Realm DB and hydrating Oatmeal models, this should be done automatically. Currently, every oatmeal model has to set the all and filter (and save) methods separately just to replace the class name, and the properties currently have to be set manually. My plan is to somehow use reflection on both the oatmeal model and the realm model to see which properties have the same name and type, and then write them from one to the other.

Currently, I have no idea how to go about this, so any hints on how I could use reflection for this would be helpful. I assume somehow use the Mirror to extract the properties and then loop through them and see if one of the same name exists in the other?

Also, to achieve this in the end, since it'll be the models doing this to return instances of itself, is it somehow possible for a model to create an array of its own type, without explicitly writing the type? E.g [Self] (which doesn't work) rather than [OatmealModel]?

I'm fairly new to Swift, but am familiar with a few other languages and concepts, any help is greatly appreciated!





Aucun commentaire:

Enregistrer un commentaire