Realm Blog

Realm Objective-C & Swift 0.98

We just released version 0.98 of Realm Objective-C and Realm Swift.

This release adds support for collection notifications, background queries, subqueries, indexing & performance improvements, bug fixes and more!

Collection Notifications

It’s now possible to register for notification blocks to be invoked whenever Realm collections are updated by calling their addNotificationBlock method.

Collection instances asynchronously invoke the block with the initial collection when registered, and then invoke it again after each write transaction which changes the collection or any items contained within it.

// Observe Results Notifications
let token = realm.objects(Person).filter("age > 5").addNotificationBlock { results, error in
    // results is identical to 'realm.objects(Person).filter("age > 5")'
    viewController.updateUI()
}

// later
token.stop()
// Observe RLMResults Notifications
self.token = [[Person objectsWhere:@"age > 5"] addNotificationBlock:^(RLMResults *results, NSError *error) {
    // results is identical to '[Person objectsWhere:@"age > 5"]'
    [myViewController updateUI];
}];

// later
[self.token stop];

See our docs on Notifications and the following API documentation for details:

Swift Objective-C
Realm.addNotificationBlock(_:) -[RLMRealm addNotificationBlock:]
AnyRealmCollection.​addNotificationBlock(_:) -[RLMCollection addNotificationBlock:]
Results.addNotificationBlock(_:) -[RLMResults addNotificationBlock:]
List.addNotificationBlock(_:) -[RLMArray addNotificationBlock:]
NotificationToken.stop() -[RLMNotificationToken stop]

This continues laying the foundation that was started with KVO support for more granular notifications. Expect more improvements in this area in the near future.

Background Queries

Working on collection notifications allowed us to improve the mechanism that kept results always “live”.

Once the query has been executed, or a notification block has been added, the Results is kept up to date with changes made in the Realm, with the query execution performed on a background thread when possible.

This change should automatically reduce work done on the main thread for apps using Results to directly back table views, which is a recommended design pattern.

Subqueries

Subqueries are now supported, enabling a whole new class of queries that were previously either impossible or inefficient to implement with Realm.

For example, here’s how you could previously model a query for companies with part time employees over 30 years old:

let partTimeOverThirty = realm.objects(Employee).filter("age > 30 AND fulltime = NO")
let companies = realm.objects(Company).filter("ANY employee IN %@", partTimeOverThirty)
RLMResults<Employee *> *partTimeOverThirty = [Employee objectsWhere:@"age > 30 AND fulltime = NO"];
RLMResults<Company *> *companies = [Company objectsWhere:@"ANY employee IN %@", partTimeOverThirty];

But this query is fairly expensive to compute and doesn’t correctly auto-update. It would also be much more complex to compare count against any value other than zero.

And now with subqueries:

let companies = realm.objects(Company).filter(
  "SUBQUERY(employees, $employee, $employee.age > 30 AND $employee.fulltime = NO)[email protected] > 0"
)
NSString *predicate = @"SUBQUERY(employees, $employee, $employee.age > 30 AND $employee.fulltime = NO)[email protected] > 0";
RLMResults<Company *> *companies = [Company objectsWhere:predicate];

However, the following limitations apply to subqueries in Realm:

  • @count is the only operator that may be applied to the SUBQUERY expression.
  • The SUBQUERY(…)[email protected] expression must be compared with a constant.
  • Correlated subqueries are not yet supported.

Indexing & Performance Improvements

It’s now possible to index BOOL/Bool and NSDate properties, as well as optional properties in Realm Swift.

Performance when deleting objects with one or more indexed properties was also greatly improved.

Breaking Changes

  • Realm Swift no longer supports Swift 1.2. The last release to support Swift 1.2 was 0.97.1.
  • +[RLMRealm realmWithPath:]/Realm.init(path:) now inherits from the default configuration.

Other Enhancements

Includes changes shipped in 0.97.1.

  • Swift: Added Error enum allowing to catch errors e.g. thrown on initializing RLMRealm/Realm instances.
  • Fail with RLMErrorFileNotFound instead of the more generic RLMErrorFileAccess, if no file was found when a realm was opened as read-only or if the directory part of the specified path was not found when a copy should be written.

Bug Fixes

Includes changes shipped in 0.97.1.

  • Fix incorrect results or crashes when using -[RLMResults setValue:forKey:] on an RLMResults which was filtered on the key being set.
  • Fix crashes when an RLMRealm is deallocated from the wrong thread.
  • Fix incorrect results from aggregate methods on Results/RLMResults after objects which were previously in the results are deleted.
  • Fix a crash when adding a new property to an existing class with over a million objects in the Realm.
  • Fix errors when opening encrypted Realm files created with writeCopyToPath.
  • Fix crashes or incorrect results for queries that use relationship equality in cases where the RLMResults is kept alive and instances of the target class of the relationship are deleted.

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