Realm Blog

Realm Objective‑C & Swift 0.99 – Fine-Grained Notifications!

We’ve released version 0.99 of Realm Objective‑C and Realm Swift!

This release adds the number one requested feature since our launch nearly two years ago: fine-grained change notifications.

We’ve also walked through the entire Objective-C and Swift APIs to clean up some unnecessary duplication and omissions. These make up several small breaking changes, but we hope you’ll find it makes the API more cohesive.

Fine-Grained Notifications

This release extends the collection notifications functionality we introduced in Realm 0.98 by adding a new changes parameter to the notification block.

This RLMCollectionChange/RealmCollectionChange parameter describes what changes have occurred at a fine-grained level, including the indices of objects that have been inserted, deleted, or modified since the last notification. This makes it possible to discretely control the animations and visual updates made to the content inside your UI, instead of arbitrarily reloading everything each time a notification occurs.

The arrays of indices follow UITableView’s batching conventions, and can be passed as-is to a table view’s batch update methods after converting to index paths in the appropriate section. Here it is in action:

Fine-Grained Notifications

For example, for a simple one-section table view, you can do the following:

notificationToken = results.addNotificationBlock { (changes: RealmCollectionChange) in
  switch changes {
  case .Initial:
    // Results are now populated and can be accessed without blocking the UI
  case .Update(_, let deletions, let insertions, let modifications):
    // Query results have changed, so apply them to the UITableView
    self.tableView.insertRowsAtIndexPaths( { NSIndexPath(forRow: $0, inSection: 0) },
        withRowAnimation: .Automatic)
    self.tableView.deleteRowsAtIndexPaths( { NSIndexPath(forRow: $0, inSection: 0) },
        withRowAnimation: .Automatic)
    self.tableView.reloadRowsAtIndexPaths( { NSIndexPath(forRow: $0, inSection: 0) },
        withRowAnimation: .Automatic)
  case .Error(let error):
    // An error occurred while opening the Realm file on the background worker thread
__weak typeof(self) weakSelf = self;
self.notificationToken = [[Person objectsWhere:@"age > 5"] addNotificationBlock:^(RLMResults<Person *> *results, RLMCollectionChange *change, NSError *error) {
  if (error) {
    NSLog(@"Failed to open Realm on background worker: %@", error);

  UITableView *tableView = weakSelf.tableView;
  // Initial run of the query will pass nil for the change information
  if (!changes) {
    [tableView reloadData];

  // Query results have changed, so apply them to the UITableView
  [tableView beginUpdates];
  [tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
  [tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
  [tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
  [tableView endUpdates];

See our docs on Collection Notifications for more information.

API Revisions

Over time, as we add new features to Realm, we need to take a step back, reviewing the entire API structure to adjust interfaces in a holistic way.

The changes can be summarized in these categories:

  1. RLMNotificationToken/NotificationTokens now only have one method to unsubscribe from notifications (-stop).
  2. Methods that had variants with and without an encryptionKey parameter have been combined.
  3. Properties that were present on both RLMRealm/Realm and RLMRealmConfiguration/Realm.Configuration have been deprecated in favor of the ones on the configuration.
  4. Methods and properties dealing with string-based Realm file paths now use NSURLs to better align with recent changes in Apple’s Foundation APIs.
  5. One Swift API we had missed in our Swift 2 transition has now shed its NSErrorPointer parameter and uses Swift’s native error handling mechanism (throws).

Here’s the complete list of Objective-C APIs that have been deprecated in favor of newer or preferred versions:

Deprecated API New API
-[RLMRealm removeNotification:] -[RLMNotificationToken stop]
RLMRealmConfiguration.path RLMRealmConfiguration.fileURL
RLMRealm.path RLMRealmConfiguration.fileURL
RLMRealm.readOnly RLMRealmConfiguration.readOnly
+[RLMRealm realmWithPath:] +[RLMRealm realmWithURL:]
+[RLMRealm writeCopyToPath:error:] +[RLMRealm writeCopyToURL:encryptionKey:error:]
+[RLMRealm writeCopyToPath:encryptionKey:error:] +[RLMRealm writeCopyToURL:encryptionKey:error:]
+[RLMRealm schemaVersionAtPath:error:] +[RLMRealm schemaVersionAtURL:encryptionKey:error:]
+[RLMRealm schemaVersionAtPath:encryptionKey:error:] +[RLMRealm schemaVersionAtURL:encryptionKey:error:]

Here’s the complete list of Swift APIs that have been deprecated in favor of newer or preferred versions:

Deprecated API New API
Realm.removeNotification(_:) NotificationToken.stop()
Realm.Configuration.path Realm.Configuration.fileURL
Realm.path Realm.Configuration.fileURL
Realm.readOnly Realm.Configuration.readOnly
Realm.writeCopyToPath(_:encryptionKey:) Realm.writeCopyToURL(_:encryptionKey:)
schemaVersionAtPath(_:encryptionKey:error:) schemaVersionAtURL(_:encryptionKey:)

Other Breaking Changes

  • Deprecate properties of type id/AnyObject. This type was rarely used, rarely useful, and unsupported in every other Realm product.
  • The block for -[RLMArray addNotificationBlock:] and -[RLMResults addNotificationBlock:] now takes another parameter, as explained above in the Fine-Grained Notifications section.

Bug Fixes

  • Fix a use-after-free when an associated object’s dealloc method is used to remove observers from an RLMObject.
  • Fix a small memory leak each time a Realm file is opened.
  • Return a recoverable RLMErrorAddressSpaceExhausted error rather than crash when there is insufficient available address space on Realm initialization or write commit.

Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Realm Team

At Realm, our mission is to help developers build better apps faster. We provide a unique set of tools and platform technologies designed to make it easy for developers to build apps with sophisticated, powerful features — things like realtime collaboration, augmented reality, live data synchronization, offline experiences, messaging, and more.

Everything we build is developed with an eye toward enabling developers for what we believe the mobile internet evolves into — an open network of billions of users and trillions of devices, and realtime interactivity across them all.

Get more development news like this