# Filter Realm Notifications in Your iOS App with KeyPaths

## Introduction

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.

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

```swift
let results = realm.objects(Company.self)
let notificationToken = results.observe() { changes in
    // 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:

```swift
public func observe(keyPaths: String]? = nil,
                                      on queue: DispatchQueue? = nil,
                                      _ block: @escaping (ObjectChange) -> 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:

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

`.observe `can alternatively take a `PartialKeyPath`:

```swift
let results = realm.objects(Company.self)
let notificationToken = results.observe(keyPaths: [\Company.orders.status]) { changes in
// 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.

## Conclusion

- `.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.