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:
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
self.tableView.reloadData()
break
case .Update(_, let deletions, let insertions, let modifications):
// Query results have changed, so apply them to the UITableView
self.tableView.beginUpdates()
self.tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) },
withRowAnimation: .Automatic)
self.tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) },
withRowAnimation: .Automatic)
self.tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) },
withRowAnimation: .Automatic)
self.tableView.endUpdates()
break
case .Error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
break
}
}
__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);
return;
}
UITableView *tableView = weakSelf.tableView;
// Initial run of the query will pass nil for the change information
if (!changes) {
[tableView reloadData];
return;
}
// Query results have changed, so apply them to the UITableView
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[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:
-
RLMNotificationToken
/NotificationToken
s now only have one method to unsubscribe from notifications (-stop
). - Methods that had variants with and without an
encryptionKey
parameter have been combined. - Properties that were present on both
RLMRealm
/Realm
andRLMRealmConfiguration
/Realm.Configuration
have been deprecated in favor of the ones on the configuration. - Methods and properties dealing with string-based Realm file paths now use
NSURL
s to better align with recent changes in Apple’s Foundation APIs. - 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 anRLMObject
. - 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.