Using Cocoa Bindings with Realm

Guilherme Rambo
Jul 10, 2017 · 3 min read

I've been working on a major update to ChibiStudio, to be launched when iOS 11 comes out later this year. One of the most important components of this project is the editor my designer uses to create and configure the item packs that are available in the iOS app. This editor is a macOS app and it needs to manage a lot of data, so there's a lot of UI to be done.

I usually prefer to write all of my UI in code, especially on iOS, but for this editor project I've been using storyboards since the first version. The app is complex so there would be a lot of boilerplate to write to get all of the UI implemented. I'll write more about the technical challenges behind ChibiStudio later on.

One of the nice things you can take advatage of when using Interface Builder on macOS projects is Cocoa Bindings. But what are Cocoa Bindings?

According to Apple:

In the simplest functional sense, the Cocoa bindings technology provides a means of keeping model and view values synchronized without you having to write a lot of “glue code.” It allows you to establish a mediated connection between a view and a piece of data, “binding” them such that a change in one is reflected in the other.

So Cocoa Bindings are a technology which allows us to connect UI components to the underlying models and keep them up to date without writing any code. You can think of them as a form of "Reactive Programming", but done visually.

This sounds very useful to my project, since the basic functionality I need to achieve is to allow my designer to edit models, so of course I need a way to have UI components interact with a database of some sort.

In this new version of the editor, I'm working with Realm as the file format. Since Realm objects are KVO-compliant, this means they support Cocoa Bindings, right? Well, not automatically.

Every change to a managed Realm object must be done inside of a write transaction, this means that if we bind a property of a Realm model to a UI component using Interface Builder, when the binding mechanism tries to call setValue:forKey:, Realm will cause our app to crash because we're trying to change a model object outside of a write transaction.

This is a bummer, but we can easily fix it with a simple little trick: all we need to do is make a parent class which all of our models will inherit from and override setValue:forKey:

Now, all we have to do is make sure the models we want to have Cocoa Bindings support inherit from ModelObject :

With this in place, all we have to do is set up bindings as usual and they will populate the UI with the values from Realm and when the UI is changed by the user, the new value will be persisted to Realm.

The video below shows the basic workflow to get Realm working with bindings on macOS:

To learn more, check out this sample project.

If you want to learn more about Realm, visit their website.

If you want to follow me on Twitter, I'm _inside.

Guilherme Rambo

Written by

I make software for iOS and Mac, write at 9to5mac.com and talk at stacktracepodcast.fm

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade