Realm Blog

Introducing Realm Xamarin

by /

Today we’re launching a new Realm mobile database, this time built specifically for Xamarin. It offers easy object persistence and full query capabilities, with a performance profile that’s faster than existing options.

Like the other editions of Realm, it is designed from the ground up to enable reactive app development, with live objects, change events, and support for unidirectional data flows.

public class Dog : RealmObject
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Owner { get; set; }
}

var realm = Realm.GetInstance();

// Query with LINQ
var puppies = realm.All<Dog>().Where(d => d.Age < 2);
puppies.Count(); // => 0 because no dogs have been added yet

// Writes in a transaction
realm.Write(() =>
{
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Rex";
    mydog.Age = 1;
});

// Queries are updated in real-time
puppies.Count(); // => 1

Realm is a database built from the ground up for the unique challenges of mobile app development, that runs directly inside phones, tablets or wearables. We launched for Java, Objective‑C, & Swift in 2014, and for React Native earlier in 2016. We are already used on hundreds of millions of devices today by appmakers including Twitter, Starbucks, Cisco, Walmart, Google, Amazon, & eBay, plus many many others.

Today, we’re launching for Xamarin, Microsoft’s mobile framework that lets developers write C# code that becomes native iOS & Android apps.

Realm Xamarin brings the modern design & simplicity you expect from Realm, and will allow you to target both iOS and Android with the same codebase. We currently support Xamarin.iOS and Xamarin.Android, and look forward to supporting Xamarin.Mac in the future, as well as UWP and Unity.

What is Realm?

Realm is not an ORM, and is not built on top of SQLite. Instead we’ve built a full database for mobile app developers, one that uses native C# objects that are dynamically mapped to a full, custom database engine (not just a key-value store). This allows us to provide a simple API while even enhancing performance. With Realm, you can model complex data, link objects in a graph, and compose advanced queries.

public class Dog : RealmObject
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Owner { get; set; }
}

var realm = Realm.GetInstance();

realm.Write(() =>
{
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Rex";
    mydog.Age = 9;
});
// Basic query with LINQ fluent or extension syntax
var oldDogs = realm.All<Dog>().Where(d => d.Age > 8);
// or
var oldDogs = from d in realm.All<Dog>() where d.Age > 8 select d;

// Queries can be chained
var dogsNamedRex = oldDogs.Where(p => p.Name == "Rex");
dogsNamedRex.Count(); // => 1

// Writes happens in a thread-safe transaction
realm.Write(() =>
{
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Rex Maximus";
    mydog.Age = 10;
});

// Query results are updated in real-time
dogsNamedRex.Count(); // => 2
public class Person : RealmObject
{
    public string Name { get; set; }
    public RealmList<Dog> Dogs { get; }
}

var realm = Realm.GetInstance();

realm.Write(() =>
{
    var jim = realm.CreateObject<Person>();
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Fido";
    mydog.Owner = jim;
});

You can see more examples of how to use these APIs in our sample apps.

Why use Realm?

Easy

Realm’s primary focus has always been ease of use, and as you can see from the samples above, Realm Xamarin has the same overall goal. After that, we’ve been working on some of the same advantages our other products are known for…

Fast

Realm’s ease of use doesn’t come at a performance cost. Because of its memory mapping, lazy loading, and custom storage engine, Realm is usually faster than SQLite despite offering a rich object-based API. Although we always recommend everyone test their own use-cases, we usually see huge speedups when porting code to Realm. See benchmark results below.

Cross-platform

This should go without saying, but Realm Xamarin obviously allows you to write your app once in C# and target both iOS & Android. Please note the Realm file format is also completely cross-platform, allowing data to be shared across iOS & Android easily. For debugging, .realm files can be opened via the Realm Browser.

Advanced

Realm objects are always up-to-date with the underlying data, making it trivial to follow reactive patterns or a unidirectional data flow. You can link Realm objects in graphs, query any property combination via LINQ, and even easily integrate Realm data in Xamarin.Forms.

Trusted

Realm Xamarin is built on top of the same core as Realm Java, Objective‑C, React Native, and Swift, which is trusted by hundreds of millions of people around the world, and used by e‑commerce applications, banks, healthcare providers, and even governments.

Community-driven

Realm Xamarin is built in the open on GitHub. Features are prioritized based on user requests and we welcome contributions.

Supported

Realm prioritizes support & bugfixes above all else. You can get answers about your database directly from the people that build & maintain it, via Stack Overflow, GitHub or Twitter.

Tests conducted on May 9, 2016, using the latest versions available of Realm, sqlite-net and Couchbase Lite. Measurements taken on an iPhone 6S Plus with 128GB memory running iOS 9.3.1. Source. We recommend you perform your own benchmarks that represents your use cases as any synthetic benchmarks can only provide rough indicators.

What’s Next

We’d love your feedback on what we can improve, and we’re particularly interested in bug reports or feature requests on our GitHub repository. Expect the API to improve significantly over the next few weeks, especially as we polish advanced features like migrations and queries.

If you are a fan of .NET and want UWP support or Unity support, please speak up — we’d love to add that in the future.

We can’t wait to see what you will build with Realm!

Read more

Realm Objective‑C & Swift 0.102 – Rename Properties in Migrations or Skip Them Altogether!

by /

Support for Xcode 6.x and Swift older than 2.2 is deprecated and will be removed entirely in our next release.

We’re releasing version 0.102 of Realm Objective‑C and Realm Swift today, adding two small migration-related features: the ability to rename properties in migrations, or to configure your Realm file to be deleted whenever a migration would have previously been required. Read on for more information.

Renaming Properties in Migrations

It’s now possible to rename properties as part of migrations. Renaming a property is more efficient than copying values and preserves relationships rather than duplicating them.

To rename a property during a migration, make sure that your new models have a property by the new name and don’t have a property by the old name.

If the new property has different nullability or indexing settings, those will be applied during the rename operation.

Here’s how you could rename Person’s yearsSinceBirth property to age:

// Inside your application(application:didFinishLaunchingWithOptions:)

Realm.Configuration.defaultConfiguration = Realm.Configuration(
  schemaVersion: 1,
  migrationBlock: { migration, oldSchemaVersion in
    // We haven’t migrated anything yet, so oldSchemaVersion == 0
    if (oldSchemaVersion < 1) {
      // The renaming operation should be done outside of calls to `enumerate(_:)`.
      migration.renamePropertyForClass(Person.className(), oldName: "yearsSinceBirth", newName: "age")
    }
  })
// Inside your [AppDelegate didFinishLaunchingWithOptions:]

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
  // We haven’t migrated anything yet, so oldSchemaVersion == 0
  if (oldSchemaVersion < 1) {
    // The renaming operation should be done outside of calls to `enumerateObjects:`.
    [migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:@"age"];
  }
};
[RLMRealmConfiguration setDefaultConfiguration:config];

Deleting Realms When a Migration is Required

It’s quite common to modify a Realm schema numerous times during development, but writing fully-fledged migrations at that stage is time consuming and distracting when you’re just trying to “get the job done”…

So in this version, we’re adding a deleteRealmIfMigrationNeeded boolean property to RLMRealmConfiguration/Realm.Configuration. This flag defaults to false so you won’t start suddenly losing data if you upgrade to this version of Realm, unless you explicitly opt in to this feature.

Bug Fixes

  • Fix crash when migrating to the new date format introduced in 0.101.0.
  • When using BETWEEN on an RLMArray/List property, only match when a single related object is within the request range, rather than allowing different objects in the list to satisfy the upper and lower bounds.
  • Fix crash when querying inverse relationships when objects are deleted.
  • Fix a race condition when a Realm is opened on one thread while it is in the middle of being closed on another thread.

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

Read more

Realm Objective‑C & Swift 0.101 – Better Dates, Memory Overhead & Crash Handling!

by /

Realm files read or written by this version cannot be opened with previous versions of Realm. Existing files will automatically be upgraded when they are opened. Please be careful about shipping updates to your existing apps!

We’re releasing version 0.101 of Realm Objective‑C and Realm Swift today, addressing some long-standing limitations regarding date precision, memory mapping overhead, multi-process crash handling, and more.

Nanosecond Precision Dates & New File Format

Until now, NSDate properties have discarded their sub-second values, leading to some surprising behavior in apps requiring sub-second precision in dates. This release includes a new date format that’s even more precise than NSDate, so date properties maintain their full precision.

This new property type format required an update to the overall Realm file format, meaning that Realm files read or written by this version cannot be opened with previous versions of Realm. Existing files will automatically be upgraded when they are opened, except for read-only files bundled with your app, which you can upgrade by opening them in the Realm Browser. Please be careful about shipping updates to your existing apps! 🚨

Reduced Multi-Threaded Memory Mapping Overhead

Previous versions of Realm needed to mmap the entire file for each thread in order to preserve transaction isolation. This isolation is why Realm doesn’t have a concept of “faults” like some other persistent data frameworks.

In this version, opening a single Realm file on multiple threads now shares a single memory mapping of the file for all threads, significantly reducing the virtual memory required to work with large files.

Improved Multi-Process Crash Handling

Crashing while in the middle of a write transaction no longer blocks other processes from performing write transactions on the same file.

You’ll recall from our previous posts on Fast Inter-Process Communication and 0.91 release announcement that Darwin doesn’t support robust inter-process mutexes 😰. So we reimplemented some of Realm’s most fundamental locking mechanisms to use fcntl(3) to emulate robust inter-process mutexes on platforms that do not support the full POSIX API for them.

This change prevents a situation where a crash in one process holding the lock, while leaving the database locked in all other processes.

Enhancements

We greatly improved the performance of the background worker for fine-grained notifications for complex object graphs, and the performance of refreshing a Realm (including via autorefresh) when there are live Results/RLMResults objects for that Realm.

Bugfixes

We fixed a crash when an RLMArray or List object is destroyed from the wrong thread.


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

Read more

Realm Java 0.90 — Better Date and API Cleanup!

by /

We just released a new version of Realm Java to this website and to Bintray. This release adds full support for the Date datatype as well as an API cleanup.

Better Date support

Realm Java has from the beginning supported the standard java.util.Date, with one limitation. We truncated all timestamps to the nearest second.

The reason was that we wanted all of our products to be compatible, even though their date formats differ widely. Starting with Realm Java 0.90 and Realm Objective-C & Swift 0.101, we have fixed these issues and Realm Java now supports the full millisecond precision that is normally offered by the Date class.

This change will require an upgrade of the format of the Realm file, but it will happen automatically when opening a Realm file using 0.90+. Enjoy all those milliseconds :D

Android Adapters

We have decided to split off all Android-specific components into their own repository. This will make it easier to release enhancements and hotfixes for those as well as keeping the general size of the main library down.

This means that from 0.90, the class RealmBaseAdapter is no longer part of the main Realm library, and you will have to add the following dependency to get it:

dependencies {
	compile 'io.realm:android-adapters:1.0.1'
}

Going forward we are planning to add more Android framework support like RecyclerView and Cursors, but if you have any other ideas or feedback, please create an issue in the new Realm Android Adapters repository.

API Cleanup

Realm Java has been in beta for roughly 1.5 years, and during that time we have gotten a lot of feedback and input on how the API should look. For that reason we are now taking the opportunity to do a general cleanup. We are removing things that are not really used and improving others.

The most important items are below:

  • All Realm classes are now final.

  • RealmChangeListeners now send the changed object as a parameter to onChange().

realm.addChangeListener(new RealmChangeListener<Realm>() {
	@Override
	public void onChange(Realm realm) {
		// A reference to Realm. Note that all Realm instances and objects
		// are live objects, so this is just convenience and it cannot
		// be compared to previous references as they will all be the same.
    }
});

Person p = realm.where(Person.class).findFirst();
p.addChangeListener(new RealmChangeListener<Person>() {
	@Override
	public void onChange(Person person) {
		person.getName(); // The updated person.
	}
});
  • All query methods on Realm and DynamicRealm have been deprecated. All query methods should be done through Realm.where(), DynamicRealm.where() or RealmCollection.where().

  • RealmConfiguration.Builder.setModules() has been renamed to RealmConfiguration.Builder.modules().

  • Realm.refresh() has been deprecated in favor of Realm.waitForChange(). See this gist for an example of how to use it. This change was motivated by the fact that one-time tasks should either use the asynchronous API’s or open a Realm instance and close it again when done with it. waitForChange() is more suited for use-cases where you can’t use the async API (because it requires a Looper thread).

calling waitForChange() will block the current Thread until a commit happens in the background or you call stopWaitForChange(), which will stop the wait of the Thread that called waitForChange().

See the full changelog for all the details.


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

Read more

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

by /

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
    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:

  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.

Read more

Realm Objective‑C & Swift 0.100 – Queryable, Live Inverse Relationships!

by /

We’re releasing version 0.100 of Realm Objective‑C and Realm Swift today, adding another highly requested feature: making inverse relationships queryable and as live as their forward counterparts.

Queryable, Live Inverse Relationships

Let’s recap how relationships work in Realm. Relationships are unidirectional, and are declared using RLMArray/List or object properties. These properties can be used in queries, and are updated automatically to reflect changes to the property value made elsewhere in your app. Realm has historically provided a method to retrieve a snapshot of all objects that link to a specific object instance at the current point in time. Realm 0.100 improves on this by allowing you to declare linking objects properties that represent the inverse side of a relationship. These properties are live, auto-updating, queryable collections that provide the full capabilities of Realm’s other collection types. Unlike other Realm properties, linking objects properties cannot be modified directly. They’re modified automatically as a result of adding or removing the object from the RLMArray/List or object property that makes up the forward side of the relationship.

One-to-Many Relationships

@interface Dog : RLMObject
@property NSString *name;
@property NSInteger age;
@property Person *owner;
@end

@implementation Dog
@end

@interface Person : RLMObject
@property NSString *name;
@property NSInteger age;
@property (readonly) RLMLinkingObjects<Dog *> *dogs;
@end

@implementation Person
+ (NSDictionary *)linkingObjectsProperties {
    return @{
        @"dogs": [RLMPropertyDescriptor descriptorWithClass:Dog.class propertyName:@"owner"],
    };
}
@end
class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0
    dynamic var owner: Person?
}

class Person: Object {
    dynamic var name = ""
    dynamic var age = 0
    let dogs = LinkingObjects(fromType: Dog.self, property: "owner")
}

Many-to-Many Relationships

@interface Person : RLMObject
@property NSString *name;
@property NSInteger age;
@property RLMArray<Person *><Person> *children;
@property (readonly) RLMLinkingObjects<Person *> *parents;
@end

@implementation Person
+ (NSDictionary *)linkingObjectsProperties {
    return @{
        @"parents": [RLMPropertyDescriptor descriptorWithClass:Person.class propertyName:@"children"],
    };
}
@end
class Person: Object {
    dynamic var name = ""
    dynamic var age = 0
    let children = List<Person>()
    let parents = LinkingObjects(fromType: Person.self, property: "children")
}

Note that due to their computed nature, RLMLinkingObjects/LinkingObjects properties must be declared as readonly/let.

The new linking objects properties offer several significant advantages over the previous approach:

1) Linking Objects Are Live, Auto-updating Collections

Just like the other collection types in Realm, RLMLinkingObjects/LinkingObjects are live and auto-updating. When new relationships are formed with or removed from the object, the linking objects will update to reflect the currently linking objects. This means you are no longer working with a static point-in-time snapshot of the relationship that you need to keep updated yourself.

2) Linking Objects Can Be Used In Queries

To perform queries on linking objects with the old API you had to manually filter the objects in your own code, missing out on the performance & liveness provided by Realm’s native query system.

Linking objects properties are completely integrated with Realm’s query system, making it efficient and easy to filter over inverse relationships.

// People that have a child that have a parent named Diane.
[PersonObject objectsWhere:@"ANY children.parents.name == 'Diane'"];

// People whose parents have an average age of > 65.
[PersonObject objectsWhere:@"[email protected] > 65"];
// People that have a child that have a parent named Diane.
realm.objects(Person).filter("ANY children.parents.name == 'Diane'")

// People whose parents have an average age of > 65.
realm.objects(Person).filter("[email protected] > 65")

3) Linking Objects Are Realm Collections

While the previous linking objects API returned a standard library array type, the new RLMLinkingObjects/LinkingObjects types conform to Realm’s collection type protocol. This makes them familiar to work with and provides all the functionality you’re used to from Realm’s RLMResults/Results types.

// Which of my parents are over the age of 56?
[self.parents objectsWhere:@"age > 56"];

// Calculate the age of my parents.
[self.parents averageOfProperty:"age"];
// Which of my parents are over the age of 56?
self.parents.filter("age > 56")

// Calculate the age of my parents.
self.parents.average("age")

Deprecations

The -[RLMObject linkingObjectsOfClass:forProperty:] and Object.linkingObjects(_:forProperty:) methods are deprecated and will be removed in a future release.

Other Changes

  • Queries that compare objects for equality now support multi-level key paths.
  • Queries that compare RLMArray / List properties using != now give the correct results.
  • Fix an assertion failure when a second write transaction is committed after a write transaction deleted the object containing an RLMArray/List which had an active notification block.

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

Read more

Realm Java 0.89 — Model and Collection interfaces!

by /

We just released a new version of Realm Java to this website and to Bintray. This release is packed with fixes and new features.

RealmModel interface

A longstanding requirement for Realm has been that all Realm model classes must extend the base class RealmObject.

Starting with 0.89, this is no longer a strict requirement and you can now choose to implement the new RealmModel interface instead.

@RealmClass
public class implements RealmModel {
	
}

You will need to manually add the @RealmClass annotation since inheriting annotations from interfaces is not yet supported by Android.

The helper methods on RealmObject are available as static methods, so if you use RealmModel you can use these methods.

Person person = getPerson();

// Extending RealmObject
person.isValid();
person.addChangeListener(listener);

// Implementing RealmModel
RealmObject.isValid(person);
RealmObject.addChangeListener(person, listener);

Extending RealmObject is still the recommended approach, but you now have the option of using the method which suits your architecture and codebase guidelines better.

Note that Realm Java still does not support extending anything other than RealmObject. That feature is still being tracked here.

RealmCollection API

The Realm Java API currently consists of two collections: RealmResults and RealmList, which both implement the standard List interface.

Both of these classes have been extended with additional Realm capabilities, but unfortunately their behavior had diverged slightly, which caused problems with RealmBaseAdapter.

In order to provide a more consistent experience, we are now introducing two new interfaces: RealmCollection and OrderedRealmCollection.

This provides a solid foundation for adding future collections as well as unifying the behavior and naming of methods across the API.

It has a few implications:

The behavior of methods like remove and clear now only operate on the collection and not the underlying Realm data. This especially impacts RealmResults where these methods will now throw UnsupportedOperationException.

  • RealmBaseAdapter now works out of the box with both RealmList and RealmResults.

  • Methods for deleting objects from both the collection and Realm are now called deleteFromRealm() or deleteAllFromRealm().

  • Realm.clear(Class) and Realm.clear() have been renamed to Realm.delete(Class) and Realm.deleteAll().

  • RealmObject.removeFromRealm() has been renamed to RealmObject.deleteFromRealm().

Stable iterators

One of the design paradigms of Realm is the concept of auto-updating results. Normally that is a great feature to have, except in one case: Changing objects in a way that would remove them from the RealmResult.

Take the following example:

RealmResults<Person> results = realm.where(Person.class).equalTo("inviteToGoogleIO", false).findAll();

// Try to invite all the people
realm.beginTransaction();
for (Person p : results) {
	p.inviteToGoogleIO(true);
}
realm.commitTransaction();

With a normal collection, you would expect to have all persons invited to Google I/O, but due to RealmResults being live-updated, it would actually only send invites to every other person. The reason is that due to the RealmResults live-updating, it would adjust the size of the collection the moment you set the first boolean field to true. This would in turn cause the iterator’s internal index to point to the next item (which hasn’t been updated), so when you call Iterator.next() or similar, it would skip over an item.

The solution so far has been to iterate backwards as that takes into account the changing size():

for (int i = results.size() - 1; i >=0; i--) {
	results.get(i).inviteToGoogleIO(true);
}

This is however very counter-intuitive. With 0.89, the auto-updating feature of RealmResults have changed slightly so instead of RealmResults being live all the time, they are now only updated on Looper events.

This means that iterators will now work as expected but also introduces a slight chance that you might accidentally access a deleted item.

RealmResults<Person> results = realm.where(Person.class).findAll();
for (Person p : results) {
	p.deleteFromRealm(); // Indirectly delete all items one-by-one.
}

// RealmResults are not updated until next Looper event
// So the RealmResult might now contain deleted objects
Person p = results.get(0); 
p.isValid() == false;

// Deleting the item directly on the RealmResults will remove them
// from the RealmResults as well
results.deleteFromRealm(0);

// and new Queries will also exclude deleted objects
results = realm.where(Person.class).findAll(); // Deleted users are removed

Read more here.

This change also impacts all RealmChangeListeners that were previously triggered after each call to Realm.commmitTransaction() on the same thread. They are now deferred to the next Looper event just like changes from other threads. This should have no effect on normal app behavior, but could potentially cause issues in unit tests that assumed that callbacks where immediately notified.

Breaking changes 🚨

PrimaryKey fields are no longer automatically marked as @Required. They can now be null if the type of the field can usually be null.

This change will throw a RealmMigrationNeededException. Either manually add @Required to the primary field to maintain the same behavior as 0.88.3 and below, or change the nullability in a migration step.

RealmObjectSchema personSchema = schema.get("Person");
personSchema.setNullable("myPrimaryKey", true);

Other improvements

See the full changelog for all the details.


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

Read more

React Native Radio Ep. 24: Realm React Native

by Tim Anglade /

On the latest episode of Devchat.tv’s React Native Radio, hosts Peter Piekarczyk and Lee Johnson sat down with Scott Kyle and Tim Anglade to talk about the recently released Realm React Native. They discuss everything from the design paradigms behind the database to the company’s business model, and get in-depth about encryption, object types, async, and more. Have you been wondering why Realm decided to directly support React Native rather than asking devs to bridge to iOS or Android? Tim and Scott reveal the thinking and product design going on behind the scenes, as well as what goes on in our underlying storage engine to make Realm so fast and easy to use. Be sure to check out the episode on Devchat.tv and subscribe on iTunes.


Play the episode below


Play on Devchat.tv

Introduction

Peter Piekarczyk: Hello and welcome to episode 24 of React Native Radio. I’m your host, Peter Piekarczyk, and we also have Lee Johnson, Scott Kyle, and Tim Anglade.

So, Scott and Tim, would you guys like to start by introducing yourselves and letting us know what you do?

Scott Kyle: I’m Scott, and I have been working on the Realm React Native binding for maybe the past 6 months or so. Before that, I co-founded a startup and we did software for WiFi routers, so a whole different thing. I was with Apple prior to that, so I’ve been bouncing around, doing lots of different stuff and enjoying every minute of it.

Tim Anglade: I’m Tim, I’m overseeing product at Realm and I’ve been with them for about 2 1/2 years, through some dark ages when we were called something else, doing something else as a startup prior to being called Realm, launching for Objective-C, Swift, Java, Android, and most recently React Native. Before that, I did a bunch of different things around NoSQL distributive systems. I came from that background and started on web originally. I’m coming back to JavaScript after a long hiatus. So that’s my back story.

Lee Johnson: All right so you piqued my interest. I didn’t realize you guys were around that long, with the dark ages comment. I’d love to hear the story of how that all transpired.

Tim Anglade: We used to be called TightDB, which was a bad name on a number of levels. We were doing something very similar. The technology hasn’t changed all too much but we were doing more of an embedded database, like a pound for pound type of replacement for SQLite. As I said, the technology hasn’t changed all that much but we’re much more focused on disk space and raw speed and a bunch of advanced features, something you couldn’t quite do with SQLite if you were into embedded systems and their devices or low level programming.

The company was really founded by a bunch of C++ dudes and was like a developers’ database type of ideal to it. We decided around early 2014 to focus more specifically on mobile, which was the founders’ first dream anyway. They both came out of Nokia and they both had worked for a long time on old mobile and new mobile. They started building a database for mobile way back when they founded the company in the late 2000s, early 2010s. A lot of the investors told them that nobody needed a mobile database so they had gone into different direction.

We took it back to the start, really focus it on what mobile was today, in the iPhone and Android world, and really focused on the Realm you see today, which is this really easy to use mobile database that has a first party integration into your language of choice, so Objective-C, Swift, Java, and specifically now JavaScript and React Native. That is the detour that we took towards building what it is today and how you always end up doing what you thought of in the first place anyway.

Realm’s Features & Use Cases

Lee Johnson: So it’d be nice if you could give us an overview of Realm’s features and use cases.

What’s cool about it is React Native is new and Objective-C and Xcode projects obviously have Core Data and Android has their database. So a database for React Native is a unique thing. It’s specific to that environment and we don’t have a lot of options for that now. You guys are pretty new to the scene for an actual database in React Native, and that makes it easier to use than writing bridges to Core Data or something crazy like that.

Tim Anglade: Realm is the umbrella term – it’s the name of the company, it’s also the name of the product that we have for each platform. In its raw form Realm is this easy to use, really fast replacement for your data model layer, including persistence, relationships, querying, and everywhere you would use a model in your app, you use a Realm object.

The basic principle of it is to build a modern data model if we were trying to rebuild SQLite today. It’s easy to use, which is what we think most developers need at this point – they really need something that doesn’t take a lot of time. When you’re developing your application and trying to maintain it and find a bug, we’re trying to do something really, really fast because you don’t want to be slowed down by an ORM or database queries and having to optimize that.

We try to maintain a really advanced feature set, like encryptions built in, graph queries built in, easy migrations, and a nice reactive notification system, and we try to do so in the open so we develop everything we can on GitHub. We support developers directly on GitHub, Stack Overflow, Twitter, or by email. We’ve tried to build a large, trusted community around it, and we are now running on half a billion devices around the world, which is pretty nice. We’re used in some really large apps on the Objective-C, Swift, Java side. We just launched JavaScript but we’ve seen some good adoption. On the older products, we’re already used by Google, Amazon, Starbucks, eBay, Budweiser, BBC, McDonald’s, Wal Mart, a bunch of global companies, which you can find on our website. That’s Realm in general.

Realm for React Native is our reinvention of the product specifically for the platform. We don’t really do bindings in the strict sense of “Let’s just take this thing we built and expose the API directly into whatever language we have to deal with.” We really try to start every new product thinking “What is that product trying to do? What is the platform trying to do? What is the framework behind it trying to do? What are its design principles and how can we fit in there in the best possible way?” We spent an enormous amount of time launching every product specifically for that community. You should look at our Swift product, it’s drastically different from our Android product in terms of the API it exposes, the query language it adds, a lot of things like that. If you look at our Swift products versus our Objective-C products, they’re also very different even though they both target the iOS platform.

Our React Native and JavaScript product is no different. We’re trying to build something that is very first party, that feels native to JavaScript, that feels like you’re interacting with a standard component of the React Native ecosystem. The jury’s still out as to whether or not we succeeded in that, so we’re always looking for feedback on everything we’re doing wrong and making improvements. It’s the application of our basic design principles around data models, around concurrency, around consistency and having different types of data you’re offloading on your app, but also applying all these things to what’s idiomatic to JavaScript and React Native. We came out with Realm for React Native very recently, and actually launched at React Conf this year. We’re lucky to have some users like TaskRabbit already using us in production for two months actually, since before we even launched publicly, and adoption’s been pretty good so far. We’re still in the early days, but we’re in the hundreds of users already after a few weeks, and we’re growing about fifteen to twenty percent every week, so we’re seeing nice exponential growth and nice pick-up in the React Native community. I’m pretty excited about that.

Peter Piekarczyk: Do you have a particular client or customer or app type that you think would most benefit from Realm? Or is it anything?

Tim Anglade: We really tried to design this for any app and for if you need a data model that would basically feel like you should be able to use Realm. Specifically on a relatively new ecosystem like the React Native ecosystem that doesn’t have a very strong integration with SQLite, like Android does, or doesn’t have a very strong framework like Core Data on iOS, we feel like there are very few reasons why you shouldn’t consider Realm for React Native. I say this because there’s a lot of trust and safety built into using the first party option in every ecosystem, so definitely there are a lot of reasons why if you’re on iOS you might still want to stick with Core Data or if you’re doing Android that you may want to use the built in SQLite functions. For React Native, there’s not the same nice, clean, first party persistence solution that has the semantics that we do and has the performance that we do. Unless you’re really happy with key-value storage, we think that you should probably give Realm a look. And again, if you don’t think we stay true to that promise, then we really would like your feedback to see how we can do that.

One of the specific use cases that tend to trigger people using us are if you need to use data offline. If you need to do complex querying, complex relationship between your objects, that’s another reason to think about it. If you need a lot of first party support from a company and not just community answers or open source projects, that’s another. There’s a bunch of different reasons to consider Realm but in terms of what apps, we really tried to invent something that should be usable by any app, whether you need offline or not, whether you need complex queries or not, no matter what business or application you’re building.

The Business Model

Peter Piekarczyk: If you don’t mind me asking, how are you guys going to make money? Because Realm is free, which is amazing, but what are your plans for the future? Offering an enterprise package?

Tim Anglade: Yeah. We’ve already generated revenue selling both services and also products around licenses to large company that need it. Our basic business model isn’t dissimilar to say, GitHub, where 90% plus of the product ends up being given away for free but it helps us build a community, build a standard on which we can up-sell a small portion of the population, to specifically ensure a sort of product that a large corporation would need. We’re looking to be a bit more public about what those offerings are in the next few months. We’re actually still learning a lot as to what people want to do on top of Realm and what specifically big corporations want out of Realm. It’s taking us a long time to refine that understanding into a nice packaged product with nice names and nice messages around them. Doing that while also taking care of launching all these new platforms and doing all support around that has been a bit of a slow ordeal but we’re going to have more announcement on that front in the next few months.

I always assume people have read the website, but in case they haven’t, the basic thing is we are free to use. All of our high level code, all of our JavaScript code in the case of React Native, is free and open sourced, Apache 2.0 on GitHub. We’ve committed to keeping that open source and to maintaining it, so it’s not going to be the case that what you’re using today is going to become paid all of a sudden. Everything that is open on GitHub will stay open on GitHub and we’ll also be actively contributing to expand it. That’s the basic promise of the business model.

Under the Hood

Lee Johnson: There are definitely a couple key features that I really love that I want to dig into shortly. But first, I just have a question about the code base for the JavaScript versus the OS side for React Native or Android side. Is it a SQLite under the covers with a bridge, or did you guys rewrite something completely different? How is that orchestrated, and could this ever develop into a node package?

Tim Anglade: The basic thing about Realm is that we don’t use SQLite. We’re not an ORM and we’re not building stuff with SQLite. So that’s different from virtually every other persistence option out there. We’re not building on LevelDB or any other key value store either. We’re built on our own underlying storage engine, which is a part of Realm that’s not open source right now, in full disclaimer. It’s something that we’re looking to open source, but it just keeps getting backlogged with everything else.

So we’re built on our own underlying storage system right now, that’s gonna go Apache 2 in the next few months. That is not strictly speaking a relational database, it’s a mix between a relational database and an object database. That powers a lot of the high-level feature that you see.

The reason why we’re able to give you a native JavaScript interface with really nice objects, and nice relationship model, and fast queries and everything else, is because we have our own storage underneath. It allows us to do a lot of really nice things, like an MVCC type storage underneath. like Git, but for your data objects. It allows us to do a lot of zero-copy things, it gives us a really nice threading model, which isn’t terribly useful of course in the case of React Native, but we hope that might change in other platforms. It’s a replacement for SQLite underneath, and at the higher-level is a replacement for an ORM, but it’s not exactly what’s happening.

There are some major differences, for example an ORM will take a copy of your data out of the database. That’s really bad for consistency, that’s really bad for resource usage, that’s really bad for speed. Whereas Realm has those two separate layers as well, like a SQLite layer, and like an ORM layer, but Realm’s layers are actually integrated to work together. We don’t copy data in and out, we give you complete consistency, everything is memory mapped all the way down. We get huge performance savings, huge ease of use improvements, and huge consistency improvements by having those two layers really tightly integrated together as opposed to the SQLite and ORM combo.

Scott Kyle: A huge portion of the Realm language bindings are shared between all the platforms within C++. Both that core storage layer that Tim was talking about and then another layer on top of that provides many of the facilities that all the language bindings need. Then we just specialize on top of that for each language. So with Swift, Objective-C, Java, they all require their own custom integration points, and we have this intermediary layer where we can make that really easy. We’re constantly improving that as well, and we do that obviously for Realm React Native as well.

Also like what Tim said, the objects that you pull out of the database, they’re not copied out. You’re just always looking at accessors to the data that’s in the database. So we can do lots of different kinds of operations very quickly that are sometimes very slow with ORMs because they have to make many queries through the database. Whereas we don’t really need to make many queries. We can do it all in one shot when the user needs it.

Tim Anglade: Yeah and there’s a specific example to give people a concrete example. If you come from a SQLite or ORM background, you have this idea of if you do a query, and that’s just a representation or projection of your data. If you want to edit the object you have to do a separate thing, and then find the object and edit it. With Realm, you don’t have to worry about that. Any time you get a query, all you get is the actual object and you can just modify them in line, for example. Again, any time you access any value in Realm, you’re not accessing some sort of derivative, or projection, or copy of it. You’re accessing the raw data itself, with a minor asterisk for consistency and refresh loops and stuff like that. This is a bit of a simplified view but you have access to everything.

Scott Kyle: We still have transactions, so when you do make modifications to your database you do that inside of a transaction. If anything does go wrong, like an exception is thrown, or even if the app itself crashed for some reason, your data should remain consistent because that transaction would not have been committed. Besides for making all your mutations inside a transaction, we try to keep the objects like their native object, like with JavaScript. Most of the Realm objects that you use, they just act like native JavaScript objects, or arrays, or whatever. So it’s really easy to use and integrate, and even pass around Realm objects into other libraries that are not even expecting a Realm object to be able to act on them.

Tim Anglade: Another quick thing to drop in there as an example of the interesting aspect of building our own core and integration thereof, is that we get to really apply a lot of reactive patterns directly into the design. Not in a very functional sense, we’re not doing streams and that stuff, but we have a really nice ability to just let you work very asynchronously, get notified of changes that are happening, and we’re doing more and more work there.

This is especially raw on the React Native side, where we still have to build in async inquiries to start with. The basic promise of the underlying engine, that you can see in the other products that we’re developing for Swift and Objective-C, and that’s on its way to React Native, is the ability to follow in a lot of really nice reactive patterns. Where you just subscribe to updates and are able to modify your UI when the underlying data changes very easily. Many people have tried and it’s very hard to build on top of SQLite or key value store, so it’s one of the nice things of being able to start fresh and build on your own foundation.

Auto-Updating Results & Listviews

Lee Johnson: That actually brings up one of the features I wanted to talk about, which is the auto-updating results which you even have for the React Native client. It’s pretty awesome especially considering the JavaScript, and iOS with its restrictions on the WebSockets and other things. For example, in iOS you’re restricted on how you can do those notifications for anything. How does that work, and could you explain the auto-updating a little bit and how it ties in? You also have a custom listview for React Native, how could those maybe be used together to show auto-updating of a listview?

Scott Kyle: Like we were talking about when you make a query into a Realm, you’re getting a view on that query that you made. So when you try to access objects inside those results, that’s when the actual query is made, and if something in the Realm changes that would affect that query. Then that query would get automatically updated so when you try to access objects out of those results again, it would give you a live representation of what the state of the Realm is at that moment.

We have change notifications but unfortunately right now they’re not super granular. So if you make a change to your Realm you’ll get a notification, but soon you’ll be able to get a change directly on a query that you made. For instance, if you have a listview – We have our own custom listview that would tie in with this very nicely. You can get a notification that something in that results changed so that you can re-render the listview. Right now we would re-render it on any change for now. It’s made to do that very efficiently because nothing has changed.

Our custom listview is not actually necessary to use to integrate Realm with a listview, it just exists to make it extra fast. For our own test purposes, we have a little app with a listview with about one million items in it, and you can scroll through it and delete them, and see them be deleted immediately. Using the stock listview, you could still use Realm with it but it would be a bit slower because of certain assumptions that it makes. So that’s why we built that, to make it extra easy and extra fast to use Realm queries, or Realm lists, inside a listview in your app.

Tim Anglade: The basic promise of what we’re building, that’s coming to React Native really quickly, is, let’s say you have a part of a UI that depends on a counter (the number of items that match a query and just one dynamic tooltip, or some sort of counter badge). You can subscribe to whether or not the results of this query have changed in any way, and then in the handler for that notification, you just recompute and redraw your UI. You don’t need to rerun the query. You don’t need to do anything because the count itself will have data automatically.

It’s super straightforward and painless to do a lot of basic UI changes. You don’t need to set up a lot of boilerplate code and you don’t need to think about the consistency of your data. It feels pretty native and fluid, with the JavaScript intact. We’re pretty excited about it – it’s pretty raw, but you can take a look at the other bindings and see what’s gonna drop in React Native very soon, as soon as we get done fixing some of these early bugs we’ve found, and support issues from the community.

Scott Kyle: This ties back in with what Tim was talking about earlier, how we have certain advantages. We’re not just building on top of SQLite, and one of the advantages of that is the deep integration from the core storage layer. When we do integrate fine-grained notifications, we won’t just get a message that something changed, we’ll be able to get a message as to exactly what changed. When updating UI components, knowing exactly what changed means you have to do a lot less recomputing diff’s and trying to figure out for yourself what changed. Again, it would just let you build an app that’s a little bit more performant.

Tim Anglade: It’s important to understand the general design patterns we have at the end of this. We fully bind to reactive patterns. I remember talking about that with Alexander, one of our two founders, and how he was pushing that when I first met him in 2013. Back then not very many people were super eager to talk about that, but it’s been driving the design of what we’ve been doing, at TightDB before even Realm, and definitely today at Realm. Whenever you’re wondering about what database we’re building, what framework we’re building, you can expect us to follow reactive patterns in everything we do.

Async

Peter Piekarczyk: How do you handle async states, loading indicators, and anything similar to that?

Scott Kyle: Right now when you query a Realm in Realm React Native, we only support synchronous queries right now, but async is coming pretty soon. Generally speaking, one of the reasons why async hasn’t been a priority for us is that we don’t generally see a performance impact unless you’re around 100,000+ items, and also asking them to be sorted in a certain way. For your regular use, standard to-do lists for normal people who don’t have 100,000 to-do’s, you don’t see much of a performance impact at all by doing live synchronous queries. That’s why we haven’t done that yet, but we are working on it, so for large databases you will be able to make asynchronous queries.

Tim Anglade: We haven’t agreed on the design specifically for that yet, but in other products that we have for Java and Swift, we let you determine what state your query is in and whether you’re still computing results, or whether you have finally computed the results, which makes it easy to update your UI accordingly.

As Scott said, in practice this is not a performance bottleneck, which I know flies in the face of a lot of “best practices” for app development, where people tell you to do all the I/O asynchronously. A lot of those best practices are designed with stuff like SQLite and ORMs in mind, and the performance improvement you get out of Realm is actually very major to the point where it’s really much closer to accessing objects in memory than it is to performing old school I/O like you’re used to with SQLite. We understand some queries still will need to be done asynchronously, but we recommend people to just enjoy the fact that they don’t have to worry about the state of their query and whether it has finished completing for most cases, and can just do a synchronous query.

Encryption

Lee Johnson: One thing I definitely want to discuss, because it’s one of the features that you guys have that really excited me, is the encryption. A lot of times, especially with SQLite for example because that’s what most people are familiar with, it’s a pain to get the SQLite cipher and get it set up. You have data on a device and devices are getting hacked all the time, and it’s in the news, now, with Apple fighting with the government over encryption.

We deal with data, but we don’t put any student data on mobile devices for that very reason. It’s just not worth the risk. But for health care applications for example or anything sensitive, can you walk through the use case and your encryption?

Tim Anglade: Encryption is one of the things that we actually had at launch for Android because we knew it was a big limiting factor on that platform. iOS already has a lot of built in encryption of files and all that stuff, so it was pretty good. For Android it was really nice to be able to just do it first party. So now we have encryption rolled out across platforms on both IOS and Android and accessible from React Native whether you’re targeting iOS or Android. To be clear though we don’t implement our own crypto, we piggy-back on either OpenSL or common crypto and we use standard AES 256 algorithm.

It’s really just like accessing any Realm you have in your application but instead of just opening it, you just have to pass the key to encrypt it or decrypt it. The only tricky part is where you store that key. You have to make sure you either get that key from somewhere secure, from a third party service, or you have to store it securely on the device. I believe there’s a library that lets you alias that across different OS’s. If you’re comfortable storing that key or getting that key from somewhere, Realm makes the encryption part very easy and uses best practice implementations from trusted 3rd party libraries. It’s definitely been mentioned as something that people like quite a bit. Getting the same level of encryption from other frameworks, especially on React Native, is really cumbersome otherwise.

Lee Johnson: Yeah, there are a lot of hoops to jump through to get any of that, but with Realm it’s literally just setting the key, right? You have a method to create the hash based on your key and then you pass it – is that how it works?

Tim Anglade: Yeah, it’s just a 64 byte key and as long as it’s correct we’ll let you open the file. I don’t have specific stats on usage but I’m always amazed because I hear about even non-health care applications or e-commerce applications using this feature, because it’s much easier than relying on platform features or other integrations. We’re really glad that we put that in. It was a bit of a complex implementation task as you can imagine to wire all that in, and we weren’t quite sure if it was worth the time we spent, but it seems to be very well-received.

Object Types

Lee Johnson: You have different object types in your models, with lists being one of those types. Can you go through the object types that you can have in your models and your schema and how they’re set up, and some of those list types, object types, and different ways you can connect data?

Scott Kyle: When you define a schema for an object, for instance, and you have a data model of a person for example, you can have your basic primitive types as properties on that person, such as string for their name and a number for their age, or a date for their birthday. We also support relationships so you can have, for instance, partner could be a pointer to another person, for instance. Or we refer to them as references to other persons. You can have lists too. You could have a list of friends and inside that list there are references to other persons, or to other objects, like pets for instance.

You define all that in your schema and then when you create those person objects or you get them out of the Realm when you query for them, you get objects that will basically behave just like native Javascript objects. You access a property like a name, and you get back a string, or you access a property called “friends” and you get back a list that basically looks and acts as much like an array as we really can make it. It has all your standard array methods, both for iterating through them and also for slicing them or pushing new objects onto them. Generally speaking it will behave as much like an array as we could make it behave. That’s list and that’s why we don’t call it array because we don’t want to mislead anyone into thinking it’s exactly an array, but generally speaking it will behave just like an array.

Tim Anglade: That name varies a little bit from platform to platform because we call it an array when we do Objective-C and we call it a list when we do it in Java. It really emulates arrays pretty closely as Scott mentioned. We think about it as “What if you just had to model your data with regular Javascript objects? How would you make that happen?” We try to give you Realm models that are as close to that as possible, that you can very intuitively understand. For example you’re going to declare your own standard properties, you’re going to link one object to another just by referencing them, and when an object references multiple other objects like a person having many cats then you’re going to use an array to do that. We wanted that syntax to be very intuitive. We don’t want you to have to worry about schemas and abstract types that are not native to your language or any other complexities, but rather you can just chain things as if they were just regular objects.

Lee Johnson: You mentioned the pointer to the actual object. There are document stores like MongoDB, where things are nested and it gets really difficult to normalize, then you have relational databases like anything Postgres, where the relationships can get really complex and can be overkill for mobile applications. Is Realm some blend between the two?

Tim Anglade: It’s more of a mix between a relational database and an object database. This is the part where it gets tricky, and I’m simplifying drastically, but the short of it is underneath, your data is in tables with rows and columns. The columns have types, and everything is neatly stored in this platform-independent format. So if you write that Realm data from React Native you can open it from Swift concurrently, for example. In both languages you’d be able to read and write the same file.

That data is always automatically mapped to an object, so when you reference another object from an object it’s just going to point you to that other table that contains the row that has the columns for the object that you want. It’s a property that lets you do a very expressive thing, like a document model, but without the overhead of every document with nested sub-documents becoming too large and complex to index or fetch in and out of memory well, because we always have independent properties accessible in memory.

It allows us to do an immense amount of lazy loading. If, for example, you’re loading an object that is graphed sequentially to every other object in your database, and it goes all the way down: object linked to an object, linked to another object, etc. Just because you load that top level object, it won’t load the rest of your graph in memory. You won’t even load any of their properties until you try to access one of those properties, because everything is just referenced. It’s a nice hybrid storage system that gives you a high level expressive object model but with the performance of a traditional table-oriented database. It’s not strictly speaking relational, because we don’t use real relational algebra and joined tables. It’s a table that consists of rows and columns, so you can isolate individual properties and values very easily and you have maximum performance there.

Read more

Realm React Native 0.11.0

by /

First off, a word of thanks for the warm reception you all gave to our newest product. Hundreds of you are already using Realm in React Native apps, and the community is growing every week. Thanks to your feedback, we were able to release version 0.11.0 of Realm React Native. We fixed a ton of bugs since our initial release, added support for indexed fields and encryption, and you can now install Realm with just one line in your terminal!

Easier setup and installation

Realm React Native is now packaged as a static library for iOS and can be setup completely from the command line using rnpm. To use the new version after updating your package.json:

  • Remove the reference to RealmJS.xcodeproj from your Xcode project (under the Libraries group)
  • Make sure rnpm is installed and up-to-date: npm install -g rnpm
  • Run rnpm link realm from your app’s root directory

Major additions

  • Support for encrypted Realms
  • List and Results are now iterable (e.g. supports for...of loops)
  • Common iteration and other methods from Array have been added to Results and List
  • Case insensitive queries are supported by adding [c] after operators
  • Support for indexed bool, string, and int properties
  • Added Realm.schemaVersion method, to check whether unopened Realms should be migrated

Major bugfixes

  • Fix for crash on Android when initializing the Realm module
  • Fix for using Chrome debug mode from a device

For the full details, check our the full release notes.


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

Read more

Introducing Realm Cocoa Converter

by /

Today, we’re launching a new open source library to complement Realm Objective-C and Realm Swift called Realm Cocoa Converter!

We’ve heard from many of our users that there are times in their development where they would like to be able to move large batches of data in and out of Realm files more easily. The goal of Realm Cocoa Converter is to provide a common library to enable importing data from other file formats into Realm, and vice-versa, exporting data from Realm.

The library is written in Swift, and is very easy to work with. For exporting a Realm file, it only takes a single class. For example, exporting to CSV:

let path = ... // Absolute path to the target Realm file
let destinationFolder = ... // Absolute path to the folder in which to save the CSV files

let exporter = CSVDataImporter(realmFilePath: path)
exporter.exportToFolderAtPath(outputFolderPath: destinationFolder)

When importing files into Realm, the process is a little more complicated. This is because Realm needs to generate a schema for each type of object in the input file before the data can be imported.

Realm Cocoa Converter handles this by having a separate class for intelligently generating the schema, which can then be either saved, or modified by the user before the import.

This schema is then supplied when the import operation takes place.

var filePaths = [String]() // An array of paths to each file representing a Realm table

// Create an instance of the schema generator and analyze the contents of those data files
let generator =  ImportSchemaGenerator(files: filePaths)
let schema = try! generator.generate()

let destinationRealmPath = ... // The destination folder for this Realm file

// Create an importer object, and import those files using the previously generated schema
let dataImporter = CSVDataImporter(files: filePaths)
try! dataImporter.importToPath(String(destinationRealmPath), schema: schema)

While Realm Cocoa Converter itself is implemented in Swift, it has also been designed to properly integrate with Objective-C and its code conventions as well.

NSString *path = ... // Absolute path to the target Realm file
NSString *destinationFolder = ... // Absolute path to the folder in which to save the CSV files

RLMCSVDataExporter *exporter = [[RLMCSVDataExporter alloc] initWithRealmFileAtPath:realmFilePath];
[exporter exportToFolderAtPath:destinationFolder withError:nil];

Currently, the library contains support for generating Realm files from groups of CSV and XLSX files, and the ability to export to CSV files. We’re planning on adding more formats in the future, including JSON and SQLite.

Realm Cocoa Converter is still very much in its infancy, and we’d love to have you help in its development! If you have any specific use-cases in your app for it, or additional formats you think it should support, please let us know!


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

Read more

Realm Java 0.88 — Better Objects!

by /

We just released a new version of Realm Java to this website and to Maven. This release includes many exciting new features.

Better Objects!

With this release, Realm for Android gives developers full control over their Realm objects. You will now be able to:

  • Add custom methods to your objects.
  • Implement interfaces.
  • Add custom logic to the getters and setters.
  • Name the accessors in any way you prefer.
  • Skip accessors altogether and make the fields public.
  • Write your own toString(), equals(), and hashCode() methods.
  • Combine Realm with Lombok.

This means that from now on, dealing with Realm objects will feel a lot more like handling normal POJOs.

In order to make this happen, we had to make Realm a Gradle plugin and not simply a library. As mentioned in a previous post this means that from now on you will have to change the way you associate Realm to your project in the build.gradle file.

buildscript {
 repositories {
    jcenter()
 }

 dependencies {
    classpath 'io.realm:realm-gradle-plugin:0.88.0'
 }
}

apply plugin: 'com.android.application'
apply plugin: 'realm-android'

This also means that from now on we will not support other build systems other than Gradle. If this seems unreasonable to you, we’ve already prepared two issues for you to vote on to re-introduce support for Maven and/or Ant.

Your opinion will lead our decision on whether and when we will implement Ant and Maven plugins.

Note that a few restrictions still apply to Realm objects:

  • Subclassing from anything but RealmObject is not allowed.
  • Fields are not allowed to be final, volatile, or transient.

Other Improvements

This release also brings a number of other improvements:

Breaking Changes 🚨

  • All notifications now use the Looper queue. Previously, when committing a transaction, all RealmChangeListeners on the same thread were triggered immediately. In order to make change listeners more predictable and consistent, they are now being delayed to the next Looper message.

  • All RxJava Observables now hold a reference to the Realm instance that created them. This means that a Realm file is now only fully closed when all Observables have been unsubscribed from. It also means that it is now possible to close a Realm instance using doOnUnsubscribe.

See the full changelog for all the details.


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

Read more

Introducing Realm React Native

by /

This post announced the launch of Realm React Native in Feb. 2016 – Since then we’ve released new features and made numerous updates. Check out the latest here in Docs.

Today at Facebook’s React.js Conference, we’re launching a new Realm mobile database built specifically for React Native. It offers easy object persistence and full query capabilities, with a performance profile that’s usually 2–10x faster than existing options.

Like the other editions of Realm, it is designed from the ground up to enable reactive app development, with live objects, change events, and support for unidirectional data flows.

Here’s how it looks:

const Realm = require('realm');

class Person {}
Person.schema = {
    name: 'Person',
    primaryKey: 'name',
    properties: {
        name: 'string',
        age: {type: 'int', default: 0},
    },
};

const realm = new Realm({schema: [Person]});

// Query
let people = realm.objects('Person', 'age >= 17');
people.length // => 0

// Write
realm.write(() => {
    savedPerson = realm.create('Person', {
        name: 'Hal Incandenza',
        age: 17,
    });
});

// Queries are updated in real-time
people.length // => 1

Realm is a database built from the ground up for the unique challenges of mobile app development, that runs directly inside phones, tablets or wearables. We launched for Java, Objective-C, & Swift in 2014, and are now used on hundreds of millions of devices today by appmakers including Starbucks, Cisco, Walmart, Google, Amazon, & eBay, plus many many others.

Today, we’re launching for React Native, Facebook’s JavaScript framework that lets developers write JS code that becomes native iOS & Android apps. (Note: Realm supports React Native, not the web framework React. We’re all in on mobile!)

Realm React Native brings the modern design & simplicity you expect from Realm, and will allow you to target both iOS and Android with the same codebase. Despite only launching to the public today, Realm React Native has already been used in production for over 2 months by TaskRabbit!

What is Realm

Realm is not an ORM, and is not built on top of SQLite. Instead we’ve built a full database for mobile app developers, one that uses native JavaScript objects that are dynamically mapped to a full, custom database engine (not just a key-value store). This allows us to provide a simple API while preserving performance. With Realm, you can model complex data, link objects in a graph, and compose advanced queries.

class Dog {}
Dog.schema = {
    name: 'Dog',
    properties: {
        name: 'string',
        age: 'int',
    }
};

let realm = new Realm({schema: [Dog]});

realm.write(() => {
    realm.create('Dog', { name: 'Rex', age: 3 });
});
// Basic query
let r = realm.objects('Dog').filtered('age < 8');

// Queries are chainable
let r2 = r.filtered('name contains "Rex"');
r2.length // => 1

realm.write(() => {
    realm.create('Dog', { name: 'Rex Maximus', age: 4 });
});

// Queries are updated in real-time
r2.length // => 2
class Person {}
Person.schema = {
    name: 'string',
    dogs: {type: 'list', objectType: 'Dog'},
};

let realm = new Realm({schema: [Dog, Person]});

realm.write(() => {
    let person = realm.create('Person', {
        name: 'Tim',
        dogs: [{name: 'rex', age: 3}],
    });
});

You can see more examples of how to use these APIs in the ReactExample app and in the JS test files.

Why use Realm?

Easy

Realm’s primary focus has always been ease of use, and as you can see from the samples above, Realm React Native is no different. After that, we’ve been working on some of the same advantages our other products are known for…

Fast

Realm’s ease of use doesn’t come at a performance cost. Because of its memory mapping, lazy loading, and custom storage engine, Realm is usually faster than SQLite or AsyncStorage despite offering a rich object-based API. Although we always recommend everyone test their own use-cases, we usually see huge speedups when porting code to Realm. See benchmark results below.

Cross-platform

Realm React Native’s API allows you to write your app once in JavaScript and target both iOS & Android, but the Realm file format is also completely cross-platform, allowing data to be shared across iOS & Android easily. For debugging, .realm files can be opened via the Realm Browser.

Advanced

Realm objects are always up-to-date with the underlying data, making it trivial to follow reactive patterns or a unidirectional data flow. You can link Realm objects in graphs, query any property combination via an expressive query language, and even easily integrate Realm data in React Native ListViews.

Trusted

Realm React Native is built on top of the same core as Realm Java, Objective-C, & Swift, which is trusted by hundreds of millions of people around the world, and used by e-commerce applications, banks, healthcare providers, and even governments. Realm React Native itself has been used by TaskRabbit in production since December 2015.

Community-driven

Realm React Native is built in the open on GitHub. Features are prioritized based on customer requests and we welcome contributions.

Supported

Realm prioritizes support & bugfixes above all else. You can get answers about your database directly from the people that build & maintain it, via Stack Overflow, GitHub or Twitter.

Tests conducted on February 19, 2016, using the latest versions available of Realm, React Native SQLite Storage for SQLite, and React Native Store for AsyncStorage. Measurements taken on an iPhone 6s running iOS 9.2.1 and a Nexus 9 running Android 5.0.1. Source.

What’s Next

Today’s release of Realm React Native is slightly less advanced than what Realm Java, Objective-C, & Swift currently offer, but it’s already trusted in production by appmakers like TaskRabbit. We’d love your feedback on what we can improve, and we’re particularly interested in bug reports or feature requests on our GitHub repository. Expect the API to improve significantly over the next few weeks, especially as we polish advanced features like migrations and queries.

If you are a fan of JavaScript but React Native is not your platform, note that we plan on adding support for Cordova/PhoneGap/Ionic, and Node.js (V8) compatibility in the future.

We can’t wait to see what you will build with Realm!

We’d like to thank TaskRabbit & the React Native team for their support. Realm React Native is much better because of their input, & we are honored to launch Realm React Native at React Conf 2016!

Read more

Realm featured on the Fragmented podcast

by /

Christian Melchior, of our Java team, was a guest on the latest episode of the Fragmented podcast to talk about the latest at Realm. Listen to the whole episode for more!

Realm was featured on the Fragmented podcast.

Thanks, Donn, for having Christian on!

Read more

Realm Objective-C & Swift 0.98

by /

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.

Read more

Installing Realm for Android: Why is it Changing?

by /

Limitations of Realm

In the year since we launched Realm for Android, we have been honored by the popularity of our library despite its limitations. In particular, we have heard many complaints about the requirement to extend classes from RealmObject, which in turns causes the following constraints:

  • No public fields
  • Only standard accessor names
  • No added logic to accessors
  • No custom methods
  • No implementing of interfaces

All these limitations come from a common reason: Realm is using proxy classes to perform zero-copy operations on the underlying data store. Let us go through all the limitations one by one.

No public fields

Java does not allow proxies to access fields, so Realm proxy classes cannot intercept when such fields are accessed. Also, fields are by definition stored in the Java heap. This means that data would have to be copied from Realm to Java memory, which is against our zero-copy practice.

Only standard accessor names

Annotations processors are extremely powerful tools, but they have some limitations. One of those is the inability to inspect the actual code of the class being proxied: only fields and methods names are available. This means that we had to rely on convention to make Realm proxy classes behave as expected.

No added logic to accessors

This is a direct consequence of the previous limitation. Since the implementation of the accessors cannot be accessed by the annotation processor, it is impossible to replicate such logic in the proxy classes. Of course we could simply call super.getMyField();, but that operates on the in-memory data, which is not being used in the proxy class.

No custom methods

Again, since the annotation processor cannot inspect code, it’s impossible to guess what a custom method actually does. Hence, Realm cannot allow such methods in order to guarantee correctness.

No implementing of interfaces

Since custom methods are not allowed, interfaces that require the implementation of methods are not allowed either.

So, How to Fix This?

The only way to overcome such limitations is with bytecode weaving. This means that after compilation is over, some modifications are applied to the .class files. We will go through the details of such operation in a future blog post. What’s important here is that the only way to cleanly perform bytecode weaving on Gradle builds is with a plugin. This is also what the popular libraries RetroLambda and Hugo are doing, so we know we are in good company!

Your build.gradle file

Until now, you installed Realm like this:

repositories {
    jcenter()
}

dependencies {
    compile 'io.realm:realm-android:<version>'
}

With the Gradle plugin, it looks like this:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "io.realm:realm-gradle-plugin:<version>"
    }
}

apply plugin: 'realm-android'

The first code sample should already be in your build.gradle file, so all you need to add are the lines staring with classpath and apply plugin: 'realm-android'.

Why Now?

Why do we provide the plugin now, even before the bytecode weaving step is released? There are actually some other reasons!

Smaller APKs!

Using the plugin we can now ship Realm as an AAR, as opposed to a JAR. We can also avoid including the annotation processor in the library and make it a standalone package. This means your final APKs will not have to include the annotation processor, shaving a few kilobytes off your app.

Easy ABI splits!

Another consequence of shipping an AAR is that now you are able to cleanly perform ABI splits without having to use the workaround described in our previous blog post. This means that you won’t have to ship a single APK containing native libraries for all CPU architectures.

What About Eclipse?

As you probably already know, Google is deprecating the ADT plugin for Eclipse and is ending its support at the end of the year. As far as we can tell, the vast majority of Android developers have already switched over to Android Studio, so that’s where we are focusing our efforts. That being said, our priorities are dictated by your feedback, and we will consider writing an Ant or Maven plugin if enough people ask for it.

Happy Coding!

We hope you will find this change useful! Please don’t hesitate to contact us. As always, we’re around on Stack Overflow, GitHub, and Twitter.

Read more