HomeLearnHow-toFilter Realm Notifications in Your iOS App with KeyPaths

Filter Realm Notifications in Your iOS App with KeyPaths

Updated: Nov 03, 2021 |

Published: Nov 03, 2021

  • Realm
  • Mobile
  • Swift
  • ...

By Eric Mossman

Rate this article


Realm Swift v10.12.0 introduced the ability to filter change notifications for desired key paths. This level of granularity has been something we've had our eye on, so it’s really satisfying to release this kind of control and performance benefit. Here’s a quick rundown on what’s changed and why it matters.

#Notifications Before

By default, notifications return changes for all insertions, modifications, and deletions. Suppose that I have a schema that looks like the one below.

Graph showing that all sub-components of the object are selected

If I observe a Results<Company> object and the name of one of the companies in the results changes, the notification block would fire and my UI would update:

1let results = realm.objects(Company.self)
2let notificationToken = results.observe() { changes in
3 // update UI

That’s quite straightforward for non-collection properties. But what about other types, like lists?

Naturally, the block I passed into .observe will execute each time an Order is added or removed. But the block also executes each time a property on the Order list is edited. The same goes for those properties’ collections too (and so on!). Even though I’m observing “just” a collection of Company objects, I’ll receive change notifications for properties on a half-dozen other collections.

This isn’t necessarily an issue for most cases. Small object graphs, or “siloed” objects, that don’t feature many relationships might not experience unneeded notifications at all. But for complex webs of objects, where several layers of children objects exist, an app developer may benefit from a major performance enhancement and added control from KeyPath filtering.

#KeyPath Filtering

Now .observe comes with an optional keyPaths parameter:

1public func observe<T: RLMObjectBase>(keyPaths: [String]? = nil, on queue: DispatchQueue? = nil, _ block: @escaping (ObjectChange<T>) -> Void) -> NotificationToken

The .observe function will only notify on the field or fields specified in the keyPaths parameter. Other fields are ignored unless explicitly passed into the parameter.

This allows the app developer to tailor which relationship paths are observed. This reduces computing cost and grants finer control over when the notification fires.

Our modified code might look like this:

1let results = realm.objects(Company.self)
2let notificationToken = results.observe(keyPaths: ["orders.status"]) { changes in
3 // update UI

.observe can alternatively take a PartialKeyPath:

1let results = realm.objects(Company.self)
2let notificationToken = results.observe(keyPaths: [\Company.orders.status]) { changes in
3 // update UI

If we applied the above snippets to our previous example, we’d only receive notifications for this portion of the schema:

Graph showing that just a single path through the Objects components is selected

The notification process is no longer traversing an entire tree of relationships each time a modification is made. Within a complex tree of related objects, the change-notification checker will now traverse only the relevant paths. This saves huge amounts of work.

In a large database, this can be a serious performance boost! The end-user can spend less time with a spinner and more time using your application.


  • .observe has a new optional keyPaths parameter.
  • The app developer has more granular control over when notifications are fired.
  • This can greatly improve notification performance for large databases and complex object graphs.

Please provide feedback and ask any questions in the Realm Community Forum.

Rate this article
MongoDB logo
© 2021 MongoDB, Inc.


  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2021 MongoDB, Inc.