[Swift; Realm] Override property’s Getter & Setter in model classes & declaring property as private

Something to know before we get started – the following is just a quick notes of some of my findings about overriding getter & setter in the property and using private properties in the models. It will be relatively short & not in-depth, but comments are welcome if you want to discuss more on these.

So, let’s get started. In the past few weeks I’m working on an iOS app with RealmSwift as the choice of the local database. This is my 1st time working with Realm APIs and I’ve encountered some issues and concerns. As mentioned before we started, one of the issue was about overriding getter & setter of the property in a Realm model class, and the concern was about “can private properties be used in the models?”

First off, we start from having a look of Setters and getters section from Realm’s document.
RealmSwift-Getter&Setter

As said, the getter & setter are already overridden by Realm, so the following code won’t work.

class Sample: Object {
    @objc dynamic var sample: String = {
        get { return self.sample }
        set { sample = "prefix" + newValue }
    }
}

In this case, Realm suggests to create an extra Realm-ignored property. I wouldn’t go for that approach as I don’t want to hold an extra property for every property in the model. Instead, the old school getter setter functions approach is what I’d go for, but it also leaves me concern on data encapsulation.

class Sample: Object {
    @objc dynamic var sample: String = ""

    func getSample() -> String {
        return self.sample
    }

    func setSample(_ str: String) {
        self.sample = "prefix" + str
    }
}

There is a problem in the code above. The String object sample has the scope of internal, means that the principle of data encapsulation has not been conformed here.

So what’s the solution? Simply declare the property as private. Now I can tell you that is the way to go as I’ve tested it, but before I wrote the unit test to confirm it works, I was a little worrying the value in private property won’t be stored into Realm database as someone told me it doesn’t work, and Realm document doesn’t mention anything about access modifiers at all! All the sample code in the documents are just using the scope of internal.

I’ve googled about using private property in Realm model class but probably it’s a very stupid question so I’ve found nothing. Therefore, I just write the unit test to find out the answer on my own.

RealmSwift-private-property-test
In the test above, UUIDKey is a subclass of Realm Object that I’ve defined for setting primary key, so the TestObject is indeed a Realm Object. And if you look down to the middle section, you can see I’m asserting the name of the test case from the object retrieve from Realm database, and that name property is declared as private.

The lowest section is the debug console. There is a line printed the name of the test case -[UUIDKeyTest testInitObject] proved that using private property in Realm Object actually works just fine.

So yeah, since the private property works as expected, I wouldn’t use the solution Realm suggests to hold extra properties just for overriding getters & setters. Declare the properties as private and write internal get set functions should be more familiar for most developers and more straightforward than the way Realm suggests.

I think that’s pretty much it for my findings about overriding getter & setter for properties in the model classes and declaring the properties as private. Next time I’ll share my experience being in Google Cloud OnBoard. Might take a few days to write that up as I’m a little too busy working on a new app atm, but it’ll be there soon.

That’s it. Bye for now.

Leave a Reply