Upgrading Realm Swift – Ditch @objc for Swift Property Wrappers

Upgrading Realm Swift – Ditch @objc for Swift Property Wrappers

What?

Realm (a persistence framework for iOS, Android, and other mobile platforms) has recently updated their SDK to better support SwiftUI and in the process they updated how Realm objects are created. This update allows us to remove @objc props and allows us to ditch the dynamic keyword. In this blog post I will walk you through the update process to bring your Realm objects into the current state of the art in Swift development.

Why?

If you just want to see the migration implementation you can click here to skip my preamble. Still reading? Good! I've been on plenty of engineering teams that never had time to prioritize cleaning up tech debt. I get it, management doesn't see the benefit of spending time on something like updating the persistence layer of the app, when the current persistence code is working just fine. But all technical debt needs to be paid off eventually and one day a product manager will ask for a new feature and they're never happy to hear a time estimate that doesn't align with their initial expectation because too much tech debt has accumulated. Those conversations are never easy or enjoyable. With that said, read on to see how you can update your Realm objects now and possibly avoid any future headaches and tech debt checks that need to be written.

How?

This is all pretty simple. I will show you a model object before and after.

Before:

@objcMembers
class MyObject: Object {
    dynamic var id: String
    dynamic var myVar1: String
    dynamic var myVar2: String?
    
    override class func primaryKey() -> String? {
        "id"
    }
}

As you can see in this implementation of MyObject we are using the @objcMembers prop on the class. This allows us to omit @objc from each var. Alternatively our model object could look like this,

class MyObject: Object {
    @objc dynamic var id: String
    @objc dynamic var myVar1: String
    @objc dynamic var myVar2: String?
    
    override class func primaryKey() -> String? {
        "id"
    }
}

Out with the old and in with the new. This next implementation uses a property wrapper and ditches the objective-c tie ins.

After:

class MyObject: Object {
    @Persisted(primaryKey: true) var id: String
    @Persisted var myVar1: String
    @Persisted var myVar2: String?
}

As you can see, we no longer are required to override the primaryKey method because the property wrapper can handle that for us. @Persisted also has an option to add an indexed parameter which looks like this,

@Persisted(indexed: true) var myIndexedVar: String

Conclusion

This update to Realm allows our code to look more "Swifty" which is always nice. But the biggest advantage to making the switch now is to avoid future technical debt. I can't wait to see what other new functionality the Realm devs can give us with the new @Persisted property wrapper. Here at Barstool Sports we are always trying to stay up to date with the latest and greatest frameworks for iOS and web. Do you want to talk more about this? Find me on Twitter, @TomRads. Or maybe you'd rather come and work with us? Checkout out the latest open positions on our jobs page.