Realm Blog

A Reactive Platform for Mobile Apps: Introducing Realm Professional Edition

by /

At Realm, our mission is to help developers build better apps faster. We have a vision for a much more powerful data layer for the mobile internet, where developers can easily build native mobile apps using live objects, where realtime data synchronization just happens automatically, and where server-side logic can be easily triggered by data changes, enabling more sophisticated features and integrations. And we’ve been hard at work making that a reality by constantly improving the Realm Mobile Database as well as the components and features of the Realm Mobile Platform.

We’re excited to share two pieces of news that advance that vision, and that make it easier for more developers to use Realm in their apps. Today we are announcing the new Realm Mobile Platform Professional Edition, a product that brings the power of the Realm platform to a larger group of developers at a new price point. We are also very happy to unveil the results of an ongoing collaboration with IBM: Scanner, a cool new Professional Edition demo app that integrates Realm with IBM Watson and provides developers with an open-source template for building reactive mobile apps that incorporate sophisticated image processing.

Realm Mobile Platform Professional Edition

Professional Edition is a new version of the Realm Mobile Platform designed for mid-sized apps and businesses. It shares all the capabilities of the free Developer Edition—notably, automatic realtime data sync—but adds key features like event handling and server-side data access (more on these below). We’ve built Professional Edition in response to customers who need these features to build the realtime apps they want to build, but who don’t yet need the high scale and other large company features of the Enterprise Edition. You can download a copy of PE today for a free 60-day trial.

The launch of Professional Edition establishes a pattern we plan to follow for a very long time: continually moving Realm features and functionality downstream, and inventing new pricing and packaging to allow greater access to more developers. We now have three versions of Realm Mobile Platform: Developer Edition, which is entirely free and available to anyone; Professional Edition, more robustly featured, aimed at medium-sized businesses, and capable of handling tens of thousands of concurrent users, starting at $1500 per month; and the fully-featured Enterprise Edition, which can handle even the largest number of users and most sophisticated apps, and is priced based on scale of use case. We work very closely with every potential customer to understand their needs, so if you have questions about editions and pricing, please reach out.

Introducing Scanner: Our Collaboration with IBM

When we shared an early version of Professional Edition with some of our contacts at IBM, they got very creative, very quickly. The result was Scanner, a Realm demo app that allows users to take a picture of anything and then quickly get a result based on sophisticated server-side image processing, including image classification, face detection, and text recognition. The app relies on the key features of Professional Edition–realtime data synchronization and event processing–as well as IBM’s Watson Visual Recognition API. You could imagine using code like this for building a variety of realtime features and apps: location identification for VR applications, face recognition for security, categorizing images for industrial and scientific applications, reading labels in retail applications, and more. But don’t spend too much time imagining, get to hacking: The demo application and all of its code (Swift and Android) are available as a free open-source project; you’ll also find there a tutorial that serves as an ideal starting point. The IBM team has also blogged about our collaboration, and has included a video of the app in action.

The pattern behind Scanner is a very common one amongst Realm Mobile Platform customers; we call it API mobilization (it’s sometimes also referred to as “API bridging”). It’s utilized when you need a highly responsive, great UX mobile app, but that app also needs to connect to and stay fully synchronized with existing APIs–could be a modern service like IBM Watson, but it’s also very often a legacy system inside the organization. The challenge for the mobile developer is that all network requests are asynchronous and can fail. We encounter many organizations with complex business logic requiring multiple API calls in a specific order. Managing the network requires additional code to orchestrate these requests, including handling the many failure scenarios. While this is a challenge on its own, each network request requires converting data into a new format, such as JSON. Again, further code is required to deal with the pain of serialization/deserialization, and bugs can easily appear when the data or schema changes.

The API mobilization pattern utilizes the Realm Platform as middleware. The mobile application uses the Realm Database (iOS or Android) on the client side, which is automatically kept in sync with the server-side data thanks to the Realm Platform. On the server side, the Realm Platform uses event handling to trigger the Watson API any time it notices a data change from the app (i.e., a new image is added); the returned data from Watson after processing the image is pushed back into Realm on the server side, and immediately synchronized with the client side. This removes the need for networking or data conversion code in your application. Mobile developers can work directly with objects in their native language relying on the Realm Database locally while the Realm Platform handles all the complexity of transferring the data.

Get Started Now

As always, we are most excited about what developers can build with Realm, so we invite you to download and install a free trial of Professional Edition, set it up with Scanner or your own app, and let us know what you think!

Read more

Realtime Collaboration, Now For Every Mobile Developer

by /

Since the release of the Realm Mobile Platform, we’ve seen how much more powerful an app becomes when developers add truly collaborative features, with multiple users sharing data with one another in realtime. The key element needed for this is client-defined access control, a feature that had been limited to paying Enterprise Edition customers. Today, we’re bringing access control to all editions of the Realm Mobile Platform, so that every mobile developer can bring realtime, multiuser collaboration to their apps – even with the free Developer Edition of the platform.

To make this all work, we’re launching new functionality in our Cocoa and Android client SDKs to expose the access control permissions on a Realm managed by Realm Object Server, so that your users can take control over who has access to their data.

It’s simple: a user who owns a Realm can share it with other users by creating a PermissionChange object, and specifying a user and a new permission for him (such as mayRead or mayWrite). After the PermissionChange object is created, that object gets saved to a special management Realm, and synced to your Realm Object Server, which will then apply the requested changes to the specified user.

Client Permission diagram

By using a dedicated synchronized Realm along with the PermissionChange object to communicate with Realm Object Server, this naturally takes advantage of Realm Mobile Platform’s objects-as-APIs approach. The PermissionChange will be synchronized automatically and Realm Object Server will react to the change and update the object with the status. Objects become the new API, making requests offline-first and immune to networking failures, and all you need to do is add some client-side code to make it work.

For more information regarding how to use the new APIs, check out the Realm Object Server documentation and relevant sections in the Cocoa and Android documentation. Then download the free Dev Edition, build something cool, and tell us about it – we’re eager to see what you can create.

Read more

Realm Objective-C & Swift 2.1 – Improved Collection Notifications!

by /

We’re releasing version 2.1 of Realm Objective‑C and Realm Swift today, which includes several improvements and bug fixes to fine-grained collection notifications. Read on to learn more!

Background (on) Notifications

The Realm SDKs have always provided a reactive, Objects-as-APIs approach to dealing with data, and with the recent launch of the Realm Mobile Platform, apps built on Realm can now easily respond to changes no matter where they originate from: other threads, processes and even other devices from half-way around the world 🌏!

With collection notifications, change information is continuously processed and delivered as operations representing what was inserted, deleted, moved and changed. Unlike ORMs that rely on diffing the old and new values, Realm’s change notifications leverage the semantic intent of operations to produce a much more accurate result, leading to nicer animations and easier code.

These notifications are always delivered asynchronously so your app never stutters or block the main UI thread. However, there are situations when changes need to be done synchronously, on the main thread, and reflected in the UI instantly. We refer to these transactions as interface-driven writes.

Interface-Driven Writes

We’ll refer to writes done on the UI thread and explicitly mirrored in the UI’s state as Interface-Driven Writes.

For example, say a user adds an item to a table view. The UI should ideally animate this operation and start this process as soon as the user initiates the action.

However, when the Realm change notification for this insertion is delivered a little later, it will indicate that an object was added to the collection backing the table view and we will once again attempt to insert a new row in the UI. This double insertion leads to inconsistent state between the UI and the backing data, which in turn will crash your app! 💥NSInternalInconsistencyException💥

Writes Skipping Notifications

To resolve this, we’re introducing a mechanism that allows for write transactions that are immediately reflected in the UI to avoid triggering a change notification for the changes that occurred during that transaction.

We’re calling these types of writes “writes skipping notifications”.

This feature especially useful when using fine-grained collection notifications with a synchronized Realm, because many of the workarounds to previously account for interface-driven writes rely on controlling the full state of when the app can perform changes. With synchronized Realms, changes are applied whenever they’re synchronized, which can happen at any point in the app’s lifetime.

Code Sample

// Add fine-grained notification block
self.notificationToken = self.collection.addNotificationBlock { [unowned self] changes in
  switch changes {
  case .Initial:
    self.tableView.reloadData()
  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: .None)
    self.tableView.endUpdates()
  case .Error(let error):
    // handle error
  }
}

func insertItem() throws {
  // Perform an interface-driven write on the main thread:
  self.collection.realm!.beginWrite()
  self.collection.insert(Item(), atIndex: 0)
  // And mirror it instantly in the UI
  self.tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: 0, inSection: 0)], withRowAnimation: .Automatic)
  // Making sure the change notification doesn't apply the change a second time
  try self.collection.realm!.commitWrite(withoutNotifying: [self.notificationToken])
}

Demo

RealmTasks Fine-Grained Notifications

Thanks to RealmTasks being open-source, the pull requests adding fine-grained notifications and writes skipping notifications can be viewed on GitHub: iOS PR #352 and macOS PR #355.

Bug Fixes

As we were building this functionality, we took the opportunity to fix a number of issues with collection notifications, so this release should make them more reliable than ever before!

  • Deliver collection notifications when beginning a write transaction which advances the read version of a Realm (previously only Realm-level notifications were sent).
  • Fix some scenarios which would lead to inconsistent states when using collection notifications.
  • Fix several race conditions in the notification functionality.
  • Don’t send Realm change notifications when canceling a write transaction.

Legacy Swift Version Support

We’d like to remind you that we will continue to support Xcode 7.3.1 and Swift 2.2 as long as we can, but encourage all our users to migrate to Xcode 8 as soon as possible.


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

The First Object Database for Node: Introducing Realm Node.js

by /

At Realm, we’re very focused on mobile developers, and have built and open-sourced Realm Mobile Database versions for Swift, Objective-C, Java, Xamarin, and React Native. But today, we’re announcing something completely different: Realm Node.js. We’re pretty sure this is the first real object database for Node, and is available today on NPM as a free and fully open source repo – just run npm install --save realm.

Over the years, we’ve had tons of requests from mobile developers for a version of Realm that worked on the server, so it’s long been on our backlog, though not highly prioritized. But our priorities changed when we released the new Realm Mobile Platform in September, and potential customers started asking us for a Node interface for the platform. We pretty quickly made Node part of the platform product strategy (more on that in a few days), and that led to the creation of Realm Node.js.

What is it, and what is it for?

Realm is an object database. It means that you simply work with objects, as you’re used to, except that these objects persist to disk easily and performantly in a Realm. You don’t have to serialize them into JSON, and you don’t have to send them through an ORM to store them in tables. You stick with the principles that object-oriented development encourages, and you make the thing you set out to make. It works on all the mobile client side platforms – and now Node.js on the server side as well.

For mobile developers, Realm Node.js means you can create and send pre-populated Realms to clients, which is very handy for a number of reasons, including getting around pesky app size limits. That’s the primary reason mobile dev have asked us for something like this over the years.

But things got even more interesting when we showed some early versions to backend developers and learned that it might be a lot more broadly useful to the Node community than we originally imagined. For example, we realized that it is useful for sharing live data between multiple Node instances. To illustrate this, we threw together a quick demo to show you how you can use Realm to get two Node processes on the same machine to work together, without the burden of serializing and deserializing the objects with which both need to work.

One of the unique features of Realm is its reactive architecture. Underneath the hood, Realm uses Multiversion Concurrency Control to provide concurrent access to the database across threads and processes. This means that readers are never blocked against a writer and each has a consistent view of the database–ensuring Realm’s ACID compliance. To coordinate this, Realm uses a notification system to update accessors when a write transaction completes. Developers can take advantage of this through Realm’s notification APIs to react to changes. This example demonstrates how a Node.js developer can use this functionality to coordinate two independent services by using Realm for interprocess communication.

In the example, we use two popular Node.js libraries: Express, a web framework, and Winston, a logging library. We will use Express to create HTTP endpoints and Winston to log information about the requests:

var express = require('express'),
    util = require('util'),
    winston = require('winston');
    RealmWinston = require('./winston-realm').Realm;

var app = express();

// Use custom Winston transport: RealmWinston
// Writes log data to winston.realm
winston.add(RealmWinston, {});

app.get('/', function (req, res) {
  res.send('Hello World!');
  winston.info('Handled Hello World');
});

app.use(function (req, res, next) {
  res.status(404).send('Sorry can not find that!');
  winston.error('404 Error at: ' + req.url);
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

To take advantage of Realm, we created a custom transport for Winston that saves the log data to a Realm file. At the base path, we log an info message confirming the “Hello World” response. For all other paths, we respond with a 404 error and log the corresponding path in an error message. By saving the log data in Realm, we can then start another Node process and register a Realm listener to react to changes:

'use strict';

var Realm = require('realm');

let winstonRealm = new Realm({
  path: 'winston.realm'
});

// Register listener to print out log messages at error level
winstonRealm.objects('Log').filtered('level = "error"').addListener((logs, changes) => {
  changes.insertions.forEach((index) => {
    let log = logs[index];
    console.log(log.message);
  })
});

The listener uses Realm’s support for collection notifications, which passes the specific changes as indexes corresponding to the inserted, deleted, or modified objects. The example adds a listener to a query of all logs at the error level and then prints the log message to the console.

While this example is simple, this setup could be used in more advanced scenarios to coordinate data across microservice architectures. Check out the complete demo here. When you’re ready to use Realm in your own Node.js projects, you can find the answers you need in our React Native documentation and our API docs (since the codebase is shared between all our JavaScript platforms).

What else can you use Realm Node.js for? Work with datasets bigger than local memory. Use as queryable and observable data structures. Build reactive architectures across multiple Node instances. Or perhaps for communication between Docker images? We’re eager to hear what you do with it!

Read more

Introducing the Realm Mobile Platform: Realtime Sync Plus Fully Open Source Database

by /

This post announced the launch of Realm Mobile Platform in Sept. 2016. Please keep in mind that some pieces may be out of date, so check out the latest here.

When we launched Realm in 2014, our goal was to help mobile developers build better apps faster by giving them a powerful alternative to SQLite and Core Data. Two and a half years later, we’ve reached more than a hundred thousand active developers and more than a billion worldwide installs of apps that use Realm. We’re extremely grateful to the developer community for the adoption, support, and feedback that has gotten us to where we are today — but we have much more to do.

Today, we’re launching the Realm Mobile Platform, a new offering that integrates our fully open-source (see below!) client-side database for iOS and Android with new server-side technology providing realtime synchronization, conflict resolution, and reactive event handling. The new platform makes it easy for mobile developers to create apps with difficult-to-build features like realtime collaboration, messaging, offline-first experiences, and more.

 

The new platform is available as a beta today, in two versions (read about our third, Pro Edition, launched in December 2016). The Developer Edition is free forever for all kinds of use cases, from hobbyists to small commercial applications, and the Enterprise Edition is available as a time-limited trial and fully supported product designed for the largest production use cases. The full details are covered below. Today the platform supports Java, Objective-C, and Swift, but React Native and Xamarin support are not far behind.

We’re also making another big change: We’re proud to be open-sourcing Realm Core, making the Realm Mobile Database fully open-source as of today — you can find the repos here. The Mobile Database is critically important to us, both as a component to the new platform and as a standalone database option for mobile developers, and we’ll continue to have engineering teams dedicated to maintaining and improving Realm Java, Realm Objective-C, Realm React Native, Realm Swift, and Realm Xamarin.

The Realm Mobile Platform

Objects All the Way Down

Even long-time Realm users may not realize that we’re an embedded object database at the core level, but it is one of our key differentiators. The ease and speed of use that developers love about Realm is a direct result of this. There is no complicated object relational mapping to wrestle with, there are only objects — so your database is your data model.

We have extended that aspect of our design philosophy to the new Object Server, and an important part of the magic behind our platform is something we call “live objects.” Live objects mean that the data objects on the device are always kept fully synchronized with the data objects on the server. Synchronization happens automatically and seamlessly — there’s no networking code to write — and is very efficient because only the changes are transmitted, not entire objects. The Realm platform also handles conflict resolution, so competing changes to shared live objects are resolved deterministically. It does this automatically by default with preset rules, and this mode will handle most use cases, but you can also easily create custom conflict resolution rules.

With Realm, you never need to think about networking. You can simply build your app with the confidence that it is working with live objects. That means all kinds of otherwise difficult-to-build features, like realtime collaboration or messaging, are a lot easier. Think, for example, about allowing users on different devices to collaborate on a shared whiteboard. The hardest parts of making that work are ensuring that changes are reflected in each user’s UI immediately, and that any conflicts — users drawing or erasing similar parts of the drawing simultaneously — are handled elegantly. The Realm platform gives you both out of the box.

Building Offline-first Experiences

The Realm platform is also a great solution for offline-first apps, where delivering a seamless user experience despite lost or intermittent connectivity is a priority. Using the Realm Mobile Database by itself gives you a very efficient, embedded database on the device, so even if the connection is dropped, your app will maintain a good user experience. It’s always been an important benefit of using the Realm Mobile Database.

But when you use the whole Realm platform — Realm Database plus the Object Server — you get much more. Automatic two-way sync just happens in the background, you can be certain that the data objects on the device are fully up-to-date as of the moment before the connection was lost. When the connection is restored, sync happens automatically again, and any conflicts that may have occurred are automatically resolved — the live objects are again fully up to date. Your users can just keep on working as if nothing happened.

Event Handling

The professional and enterprise versions of the Realm platform include another key feature: a server-side event handling framework that provides the plumbing required to easily trigger server-side logic whenever an object changes. You can configure this framework to listen for object changes from the device side and to then instantly run server code in response. Perhaps a user enters a coupon code while filling out an order form. This is captured locally as a change to the device-side coupon object, which syncs to the server instantly. That specific change causes the event handling framework to trigger a check of the coupon code against valid codes, updating the server-side coupon object with a response about the validity. This response is then synced back down to the device-side coupon object triggering a notification that updates the UI.

Event handling

You can use event handling to build integrations to existing APIs and infrastructure, allowing the Realm Object Server to serve as an API bridge or mobilization middleware. It also enables you to design your app around “serverless” computing principles — you can write discrete functions for each specific trigger.

Get Started Today

The Realm Mobile Platform is available in three versions (as of December 2016). You can download the free Developer Edition, start a free trial of Professional Edition, which includes event handling, or request a demo of Enterprise Edition. Compare features and editions here.

Read more

Realm Objective-C & Swift 2.0 – Mobile Platform Support

by /

We’re releasing version 2.0 of Realm Objective‑C and Realm Swift today, adding support for the Realm Mobile Platform. Also included in this release is one source breaking change for Swift 3 and bug fixes. Read on to learn more!

Realm Mobile Platform Extensions

If you haven’t read the Realm Mobile Platform launch post yet, please do that now so we can get back to the technical cocoa bits! (err, nibs? 😄)

Let’s start with a quick look at what it takes to configure a synchronized Realm:

// Authenticating the User
User.authenticate(with: .google("google token"),
                  server: URL(string: "https://realm.example.com:9443")) { user, error in
  if let user = user {
    // Opening a remote Realm
    let realmURL = URL(string: "realm://realm.example.com:9080/~/userRealm")!
    let config = Realm.Configuration(syncConfiguration: (user, realmURL))
    let realm = try! Realm(configuration: config)
    // Any changes made to this Realm will be synced across all devices!
  } else if let error = error {
    // handle error
  }
}

That’s it! Once a Realm is opened like this, any changes made to it will be automatically synchronized across all other devices for that user.

Back to technical bits. To support the Mobile Platform, we’ve added some new classes and APIs:

Sync User & Credential

Sync Users are a central concept when dealing with synchronized Realms. Every Realm is associated with a user. The user can be authenticated to a Realm via a username/password credential or through a number of additional authentication methods (Google, Facebook, iCloud, etc.). See docs on users for details.

Sync Configuration

To configure a synchronized Realm, you must set the syncConfiguration property of RLMRealmConfiguration/Realm.Configuration with the user and the remote realm URL (e.g. realm://realm.example.com:9080/~/userRealm). See our docs for more details.

Sync Manager & Session

The sync manager (RLMSyncManager/SyncManager) is a singleton (for the time being) that manages all synchronized Realms. You’ll mostly interact with it to set the sync engine’s log level, or to specify a global error handler.

Each synchronized Realm has a corresponding session (RMLSyncSession/SyncSession) which can provide further information about its state. We intend to attach more information to this in upcoming releases.

Platform Extensions are in Beta

Although the underlying technology for Realm synchronization has been built, refined and stabilized over the last 5 years, we want to make sure we get the APIs right before committing to them. So we’re releasing the platform extensions as a beta. These APIs will change in future releases. We’re doing this to make sure we end up with the best possible product.

If your app doesn’t use the platform extensions, you can continue to count on the reliability of Realm just like you always have. The platform extensions have been designed in a way that clearly differentiates from using Realm entirely locally or using a synchronized Realm, so this should be easy to identify if your app relies on any of the beta components.

A (mostly) non-breaking 2.0 release

This is a major version bump for our frameworks to reflect the magnitude of the new features and capabilities included in this release. However, we’ve chosen to not introduce API breaking changes, because we realize this release comes just a few months after our 1.0 release and we value the time it takes for you, our users, to update your apps for API changes. With one exception… In Realm 1.1.0 we introduced official Swift 3 APIs and the most common feedback we got there was how it wasn’t ideal that RealmSwift.Error conflicted with the standard library Swift.Error. So by popular demand, we’ve nested our Error into a Realm extension, and this is the only source-breaking change in this release.

Note that Realm Objective-C and Swift 2.0 introduces a new file format that allows us to gain performance improvements and fix some bugs. Files written by Realm 2.0 cannot be read by 1.x or earlier versions. Old files can still be opened.

Removing some extra files

The .log, .log_a and .log_b files no longer exist and the state tracked in them has been moved to the main Realm file. This reduces the number of open files needed by Realm, improves performance of both opening and writing to Realms, and eliminates a small window where committing write transactions would prevent other processes from opening the file.

Bug Fixes

  • Fix an assertion failure when sorting by zero properties.
  • Fix a mid-commit crash in one process also crashing all other processes with the same Realm open.
  • Properly initialize new nullable float and double properties added to existing objects to null rather than 0.
  • Fix a stack overflow when objects with indexed string properties had very long common prefixes.
  • Fix a race condition which could lead to crashes when using async queries or collection notifications.
  • Fix a bug which could lead to incorrect state when an object which links to itself is deleted from the Realm.

Q: Can I use Realm with its newly open sourced core storage engine?

Yes! You can build and use Realm as an embedded database built 100% from open source components. Although the installation steps are a bit more involved than pod install, but you can follow the instructions listed in the READMEs for both realm-core and realm-cocoa.

We’re working on adding a way to install entirely from source using CocoaPods in the next few weeks. Stay tuned!

We’d like to remind you that we will continue to support Xcode 7.3.1 and Swift 2.2 as long as we can, but encourage all our users to migrate to Xcode 8 as soon as possible.


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 2.0 - Mobile Platform Support

by /

We’re releasing version 2.0 of Realm Java today, adding support for the Realm Mobile Platform as well as some other minor changes and bug fixes.

Realm Mobile Platform Extensions

If you didn’t read the Realm Mobile Platform launch post yet, we suggest you do that now in order to make more sense of the technical details that will soon follow.

First you need to enable the Mobile Platform Extensions by adding the following to your app’s build.gradle file:

realm {
  syncEnabled = true
}  

Then, let’s take a quick look at what it takes to configure a synchronized Realm:

// Login a user
Credentials credentials = Credentials.usernamePassword(username, password, true);
User.loginAsync(credentials, "https://realm.example.com:9443", new User.Callback() {
  @Override
  public void onSuccess(User user) {
    // Opening a synchronized Realm
    // All changes to this Realm will be synchronized with all devices
    SyncConfiguration config = new SyncConfiguration.Builder(user, "realm://realm.example.com/~/userRealm").build();
    Realm realm = Realm.getInstance(config);
  }
  
  @Override
  public void onError(ObjectServerError error) {
    // Handle error
  }
});

That’s it! Once a Realm is opened like this, any changes made to it will be automatically synchronized across all other devices for that user.

Back to the technical bits. To support the Realm Mobile Platform, we’ve added some new classes and APIs:

User & Credential

Users are a central concept when dealing with synchronized Realms. Every Realm is associated with a user. The user can be authenticated to a Realm via a username/password credential or through a number of additional authentication methods (Google, Facebook, iCloud, etc.). See docs on users for details.

Sync Configuration

To configure a synchronized Realm, you must create a SyncConfiguration tied to the user and the remote Realm URL (e.g., realm://realm.example.com/~/userRealm). See our docs for more details.

Sync Manager & Session

The SyncManager is a singleton that manages all synchronized Realms. Currently, you will most likely interact with it to specify a global error handler or how users are stored.

Each synchronized Realm has a corresponding Session which can provide additional information about its state. We intend to attach more information to the session in upcoming releases.

Platform Extensions are in Beta

Although the underlying technology for Realm synchronization has been built, refined and stabilized over the last 5 years, we want to make sure we get the APIs right before committing to them. So we’re releasing the platform extensions as a beta. These APIs will change in future releases. We’re doing this to make sure we end up with the best possible product. Feedback on the APIs is appreciated.

If your app doesn’t use the platform extensions, you can continue to count on the reliability of Realm just like you always have. The platform extensions have been designed in a way that clearly differentiates from using Realm entirely locally or using a synchronized Realm. This should make easy to identify if your app relies on any of the beta components.

All APIs that are in beta are marked with a @Beta annotation and tag in respectively code and Javadoc.

Other 2.0 changes

This is a major version bump for our frameworks to reflect the magnitude of the new features and capabilities included in this release. At the same time we have streamlined a few things as well as made a few adjustments to bring the Realm Java more in line with Realm Swift and Realm Objective-C.

Note that Realm Java introduces a new file format that allows us to gain performance improvements and fixes some bugs. Files written by Realm 2.0 cannot be read by 1.x or earlier versions. Old files can still be opened and they will be migrated to the new format automatically. NOTE: If you are shipping prebuild Realm files with your app, you have to upgrade those to the new version. You can use Realm Browser to upgrade to the latest file format.

Global initializer

The Context reference was sneaking into more and more of our APIs, causing unnecessary friction. In the end we took a step back and introduced a global initializer function

Realm.init(context);

This also made it possible to remove the context from other parts of the APIs which means that:

  • Creating a RealmConfiguration.Builder() no longer requires a context.
  • RealmConfiguration.Builder.assetFile() no longer requires a context.
  • Realm.getDefaultInstance() now works without setting a default first.
  • More failsafe loading of native code.

A natural place for calling this method is in an Application subclass:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Realm.init(this);
        // Other initializers
    }
}

Default Values

With Realm Java 2.0 we support default values when creating objects. This implies that it is possible to define default values for fields and in the default constructor.

public class Person extends RealmObject {
  private String name = "John";
  private int age;
  
  public Person() {
    this.age = 42;
  }
}

Person p = realm.createObject(Person.class);
p.getName(); // John
p.getAge(); // 42

Default values will also be applied when creating objects from JSON data, but not when creating objects using the dynamic API.

RealmLog

A new class has been added to the public API called RealmLog. It makes it possible to customize how much is logged from Realm and how. All events from the Realm Mobile Platform are also routed through this class.

RealmLog.clear(); // Remove all loggers
RealmLog.add(new AndroidLogger(Log.DEBUG)); // Add custom logger

Objects with Primary Keys

In order to support merging objects from other devices, two new restrictions are imposed on objects with primary keys:

1) A primary key must be provided when the object is created. 2) Once a primary key is set it cannot be changed.

First restriction should only be visible if you use realm.createObject(Class) to create objects. In that case it is required to set the value of the primary key by using realm.createObject(Class, Object).

Using realm.copyToRealm() and realm.createObjectFromJson() will continue to work as before.

If you, for some reason, need to change the primary key, it is necessary to create a new object and copy all fields over. copyFromRealm()/copyToRealm() can be used to make that process easier.

Bug fixes and other changes

For a full list of bug fixes and other changes, see the Changelog.


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 1.1.0 – Official Swift 3 APIs & Xcode 8 Support

by /

We will continue to support Xcode 7.3.1 and Swift 2.2 as long as we can, but encourage all our users to migrate to Xcode 8 as soon as possible.

We’re releasing version 1.1.0 of Realm Objective‑C and Realm Swift today, adding support for Xcode 8, Swift 2.3, Swift 3.0, with frameworks linked against iOS 10, macOS 10.12, tvOS 10 and watchOS 3. Also included in this release are some minor non-breaking API improvements, performance improvements and bug fixes. Read on to learn more!

Swift 3 API Refinements

Those of you keeping up with changes to Swift already know how big a jump Swift took from versions 2.x to 3.0!

We’ve audited Realm Swift’s public API in preparation for this and made some adjustments to reflect changes to Swift’s syntax and API design guidelines. We strived to strike a balance between conforming to the API guidelines without drastically changing ours APIs at their call site (i.e., in your code), so changes to your code should be minimal…

Here are some examples of how Realm Swift looks in Swift 2.2 and Swift 3.0:

// Swift 2.2/2.3
let config = Realm.Configuration(
  schemaVersion: 1,
  migrationBlock: { migration, oldSchemaVersion in
    migration.renamePropertyForClass(Person.className(), oldName: "yearsSinceBirth", newName: "age")
    migration.enumerate(Person.className()) { oldObject, newObject in
      // Migrate Person
    }
  }
)

let realm = try! Realm(configuration: config)
let sortedDogs = realm.objects(Dog.self).filter("color = 'tan'").sorted("name")
let jim = Person()
try! realm.write {
  jim.dogs.appendContentsOf(sortedDogs)
}

// Swift 3.0
let config = Realm.Configuration(
  schemaVersion: 1,
  migrationBlock: { migration, oldSchemaVersion in
    migration.renameProperty(onType: Person.className(), from: "yearsSinceBirth", to: "age")
    migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
      // Migrate Person
    }
  }
)

let realm = try! Realm(configuration: config)
let sortedDogs = realm.objects(Dog.self).filter("color = 'tan'").sorted(byProperty: "name")
let jim = Person()
try! realm.write {
  jim.dogs.append(objectsIn: sortedDogs)
}

For simplicity, our documentation throughout the site has been updated to use Swift 3 exclusively. That includes code samples, long form docs and API docs.

API breaking changes

  • Deprecate migrateRealm: in favor of a new performMigrationForConfiguration:error: method that follows Cocoa’s NSError conventions.
  • Fix an issue where RLMResults used id instead of its generic type as the return type of subscript.

Enhancements

  • Improve error message when using NSNumber incorrectly in Swift models.
  • Further reduce the download size of the prebuilt static libraries.
  • Improve sort performance, especially on non-nullable columns.
  • Allow partial initialization of an object by initWithValue:, deferring required property checks until the object is added to a Realm.

Bug Fixes

  • Fix incorrect truncation of the constant value for queries of the form column < value for float and double columns.
  • Fix a crash when an aggregate is accessed as an Int8, Int16, Int32, or Int64.
  • Fix a race condition that could lead to a crash if an RLMArray or List was deallocated on a different thread than it was created on.
  • Fix a crash when the last reference to an observed object is released from within the observation.
  • Fix a crash when initWithValue: is used to create a nested object for a class with an uninitialized schema.
  • Enforce uniqueness for RealmOptional primary keys when using the value setter.

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 1.1.0 — New and faster Insert API!

by /

We just released a new version of Realm Java to this website and to Bintray. It contains a new insert API as well as a number of bug fixes.

Insert API

Realm’s storage engine has always been faster than SQLite when it comes to inserting data, but due to a number of design decisions in the Realm Java API, that advantage was mostly lost. This meant that Realm was generally as fast as SQLite for a small number of items (<1000), but started getting slower the more items you added in a batch.

In v1.1.0 we came up with some optimizations and now offer 4 new methods:

  • void Realm.insert(RealmModel obj)
  • void Realm.insert(Collection collection)
  • void Realm.insertOrUpdate(RealmModel obj)
  • void Realm.insertOrUpdate(Collection collection)
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.insertOrUpdate(restApi.getPersons());
realm.commitTransaction();

These methods differ mostly from the standard Realm.copyToRealm() in the sense that they do not return any objects. This has allowed us to reduce memory allocations to almost zero as well as remove many checks that were pure overhead.

Doing this, we went from being ~40% slower than an optimized SQLite implementation to being ~70% faster for 100K objects.

Realm Batch Insert Benchmark

We have released our benchmarks repo so you can verify these numbers yourself. Find it here. The numbers above were produced on a Nexus 6P using stock Android 6.0.1.

Note that due to Realm’s auto-update features it is possible to query for data before they are even saved, and you will get notified when the data is available. This can be a huge benefit for those of you that want to separate displaying data from saving it:

final PersonApi api = new PersonApi();
Realm realm = Realm.getDefaultInstance();
RealmResults<Person> persons = realm.where(Person.class).findAllAsync();
person.addChangeListner(new RealmChangeListener() {
    @Override
    public void onChange(RealmResults<Person> persons) {
      if (!persons.isEmpty()) {
	    // Callback when data is available
      }
  }
});

realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
      realm.insertOrUpdate(api.getPersons());
    }
});

Bug fixes

  • Combining async transactions and async queries on the UI thread could result in the transaction onSuccess callback being invoked before the data is available on the UI thread.

  • The RealmOptionalAPITransformer introduced in 1.0.1 does not work with DexGuard and has been disabled for now.

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 Xamarin 0.76.0 released

by /

We’ve released version 0.76.0 of Realm Xamarin. This includes the first external contribution, by Joe Brock: support for INotifyPropertyChanged. This adds change notifications to your Realm objects when using data binding with Xamarin Forms. For more information, see From Data Bindings to MVVM in the Xamarin Docs. NuGet should already be telling you that the update is available in existing projects and new projects that you add it to will use the new version out of the box.

Major Changes

  • RealmObject classes will now implicitly implement INotifyPropertyChanged if you specify the interface on your class. Thanks to Joe Brock for this contribution!

Minor Changes

  • long is supported in queries
  • Linker error looking for System.String System.String::Format(System.IFormatProvider,System.String,System.Object) fixed
  • Second-level descendants of RealmObject and static properties in RealmObject classes now cause the weaver to properly report errors as we don’t (yet) support those.
  • Calling .Equals() on standalone objects no longer throws.

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 Xamarin 0.75.0 released

by /

We’ve released version 0.75.0 of Realm Xamarin. This is the first release after the launch, introducing some essential features and fixes. NuGet should already be telling you that the update is available in existing projects and new projects that you add it to will use the new version out of the box.

Breaking Changes

  • File format of Realm files is changed. Files will be automatically upgraded but opening a Realm file with older versions of Realm is not possible. NOTE: If you were using the Realm Browser specified for the old format you need to upgrade. Pick up the newest version here.
  • RealmResults<T> no longer implicitly implements INotifyCollectionChanged. Use the new ToNotifyCollectionChanged method instead.

Major Changes

  • RealmResults<T> can be observed for granular changes via the new SubscribeForNotifications method.
  • Realm gained the WriteAsync method which allows a write transaction to be executed on a background thread.
  • Realm models can now use byte[] properties to store binary data.
  • RealmResults<T> received a new ToNotifyCollectionChanged extension method which produces an ObservableCollection<T>-like wrapper suitable for MVVM data binding.

Minor Fixes

  • Nullable DateTimeOffset properties are supported now.
  • Setting null to a string property will now correctly return null
  • Failure to install Fody will now cause an exception like “Realms.RealmException: Fody not properly installed. RDB2_with_full_Realm.Dog is a RealmObject but has not been woven.” instead of a NullReferenceException
  • The PCL RealmConfiguration was missing some members.
  • The Fody weaver is now discoverable at non-default NuGet repository paths.

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

13,949 Commits and 6,148 Closed Issues Later: Thank You for Helping Realm Reach 1.0

by /

It was July of 2014 when we announced Realm as “the first mobile-first database.” Today — 13,949 commits and 6,148 closed issues later — we’re proud to release Realm 1.0, a major milestone not only for Realm as a company and a product, but also for the iOS and Android developer communities that have embraced Realm.

When we launched, we only offered an Objective-C version of Realm for iOS and Mac developers. First-class support for Swift and an Android version were added later, and just recently we launched initial support for React Native and Xamarin. As a result, Realm is now available to every major mobile platform and programming language. This release is the culmination of more than two years of hard work building and shipping products, and we could not have gotten here without the tremendous support of the community. Thank you! 👏

Even before reaching 1.0, Realm has been broadly adopted by the mobile dev community. You’ve given us over 12,000 stars on GitHub (and counting). Realm is currently used by more than 100,000 active developers and in tens of thousands of apps, including apps with massive usage from companies like Starbucks, Twitter, Anheuser-Busch, NBCUniversal, Alibaba, eBay, and thousands more. They are using Realm because Realm makes their apps better — the developers behind those apps can build better user experiences, more easily and more quickly. With today’s 1.0 release, they can be further assured that Realm products for iOS and Android have reached a key stage of maturity and stability.

To see what has changed, you can look at our changelogs for Java, Objective-C, and Swift.

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

// Define you model class by extending RealmObject
public class Dog extends RealmObject {
    private String name;
    private int age;

    // ... Generated getters and setters ...
}

public class Person extends RealmObject {
    @PrimaryKey
    private long id;
    private String name;
    private RealmList<Dog> dogs; // Declare one-to-many relationships

    public Person(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // ... Generated getters and setters ...
}

// Use them like regular java objects
Dog dog = new Dog();
dog.setName("Rex");
dog.setAge(1);

// Create a RealmConfiguration that saves the Realm file in the app's "files" directory.
RealmConfiguration realmConfig = new RealmConfiguration.Builder(context).build();
Realm.setDefaultConfiguration(realmConfig);

// Get a Realm instance for this thread
Realm realm = Realm.getDefaultInstance();

// Query Realm for all dogs younger than 2 years old
final RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
puppies.size(); // => 0 because no dogs have been added to the Realm yet

// Persist your data in a transaction
realm.beginTransaction();
final Dog managedDog = realm.copyToRealm(dog); // Persist unmanaged objects
Person person = realm.createObject(Person.class); // Create managed objects directly
person.getDogs().add(managedDog);
realm.commitTransaction();

// Listeners will be notified when data changes
puppies.addChangeListener(new RealmChangeListener<RealmResults<Dog>>() {
    @Override
    public void onChange(RealmResults<Dog> results) {
        // Query results are updated in real time
        puppies.size(); // => 1
    }
});

// Asynchronously update objects on a background thread
realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm bgRealm) {
        Dog dog = bgRealm.where(Dog.class).equals("age", 1).findFirst();
        dog.setAge(3);
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() {
      // Original queries and Realm objects are automatically updated.
      puppies.size(); // => 0 because there are no more puppies younger than 2 years old
      managedDog.getAge();   // => 3 the dogs age is updated
    }
});
// Define your models like regular Objective‑C classes
@interface Dog : RLMObject
@property NSString *name;
@property NSData   *picture;
@property NSInteger age;
@end
@implementation Dog
@end
RLM_ARRAY_TYPE(Dog)
@interface Person : RLMObject
@property NSString             *name;
@property RLMArray<Dog *><Dog> *dogs;
@end
@implementation Person
@end

// Use them like regular Objective‑C objects
Dog *mydog = [[Dog alloc] init];
mydog.name = @"Rex";
mydog.age = 1;
mydog.picture = nil; // properties are nullable
NSLog(@"Name of dog: %@", mydog.name);

// Query Realm for all dogs less than 2 years old
RLMResults<Dog *> *puppies = [Dog objectsWhere:@"age < 2"];
puppies.count; // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
  [realm addObject:mydog];
}];

// Queries are updated in real-time
puppies.count; // => 1

// Query and update the result in another thread
dispatch_async(dispatch_queue_create("background", 0), ^{
  Dog *theDog = [[Dog objectsWhere:@"age == 1"] firstObject];
  RLMRealm *realm = [RLMRealm defaultRealm];
  [realm beginWriteTransaction];
  theDog.age = 3;
  [realm commitWriteTransaction];
});
// Define your models like regular Swift classes
class Dog: Object {
  dynamic var name = ""
  dynamic var age = 0
}
class Person: Object {
  dynamic var name = ""
  dynamic var picture: NSData? = nil // optionals supported
  let dogs = List<Dog>()
}

// Use them like regular Swift objects
let myDog = Dog()
myDog.name = "Rex"
myDog.age = 1
print("name of dog: \(myDog.name)")

// Get the default Realm
let realm = try! Realm()

// Query Realm for all dogs less than 2 years old
let puppies = realm.objects(Dog).filter("age < 2")
puppies.count // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
try! realm.write {
  realm.add(myDog)
}

// Queries are updated in real-time
puppies.count // => 1

// Query and update from any thread
dispatch_async(dispatch_queue_create("background", nil)) {
  let realm = try! Realm()
  let theDog = realm.objects(Dog).filter("age == 1").first
  try! realm.write {
    theDog!.age = 3
  }
}
// Define your models and their properties
class Car {}
Car.schema = {
  name: 'Car',
  properties: {
    make:  'string',
    model: 'string',
    miles: 'int',
  }
};
class Person {}
Person.schema = {
  name: 'Person',
  properties: {
    name:    {type: 'string'},
    cars:    {type: 'list', objectType: 'Car'},
    picture: {type: 'data', optional: true}, // optional property
  }
};

// Get the default Realm with support for our objects
let realm = new Realm({schema: [Car, Person]});

// Create Realm objects and write to local storage
realm.write(() => {
  let myCar = realm.create('Car', {
    make: 'Honda',
    model: 'Civic',
    miles: 1000,
  });
  myCar.miles += 20; // Update a property value
});

// Query Realm for all cars with a high mileage
let cars = realm.objects('Car').filtered('miles > 1000');

// Will return a Results object with our 1 car
cars.length // => 1

// Add another car
realm.write(() => {
  let myCar = realm.create('Car', {
    make: 'Ford',
    model: 'Focus',
    miles: 2000,
  });

// Query results are updated in real-time
cars.length // => 2
// Define your models like regular C# classes
public class Dog : RealmObject 
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Owner { get; set; }
}

public class Person : RealmObject 
{
    public string Name { get; set; }
    public RealmList<Dog> Dogs { get; } 
}

var realm = Realm.GetInstance();

// Use LINQ to query
var puppies = realm.All<Dog>().Where(d => d.Age < 2);

puppies.Count(); // => 0 because no dogs have been added yet

// Update and persist objects with a thread-safe transaction
realm.Write(() => 
{
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Rex";
    mydog.Age = 1;
});

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

// LINQ query syntax works as well
var oldDogs = from d in realm.All<Dog>() where d.Age > 8 select d;

// Query and update from any thread
new Thread(() =>
{
    var realm2 = Realm.GetInstance();

    var theDog = realm2.All<Dog>().Where(d => d.Age == 1).First();
    realm2.Write(() => theDog.Age = 3);
}).Start();

Why use Realm?

Easy

Realm’s primary focus has always been ease of use. Developers tell us they switch even large apps to Realm in hours, and save weeks of implementation, optimization & debugging time on an average project.

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 raw SQLite, despite offering a rich object-based API. Although we always recommend that everyone test their own use-cases, developers usually see huge speedups when porting apps to Realm.

Cross-platform

Realm supports Java, Objective-C, React Native, Swift and Xamarin. You can share Realm files across platforms, use the same data models, and write similar business logic on all platforms. For debugging, .realm files can be opened with 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, use an advanced query language, rely on built-in AES256 encryption, and even easily integrate Realm data into your UI through optional add-ons.

Trusted

Have a large app or a large userbase? Realm’s the database for you. We’re already trusted in production by banks and healthcare providers, and proven across complex enterprise apps and #1 hits on both the Apple App Store and Google Play Store.

Community-driven

Realm is built in the open on GitHub. Features are prioritized based on user requests and we welcome contributions. We have over 12,000 stars on GitHub, and beyond the core projects, our community has already been building hundreds of apps, plugins & components.

Supported

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

Who is using Realm?

Realm is built into apps used by over a billion people.

Twitter

Even #1 app store successes trust Realm. Twitter’s innovative video app Vine and its 200M monthly active users started using Realm in 2016.

Starbucks

The Fortune 500 retailer relies on Realm in their flagship app, allowing you to order ahead from your phone and reap rewards at the counter.

Alibaba

The NYSE-listed Chinese juggernaut uses Realm in its flagship marketplace business, allowing both suppliers & buyers to sell & buy goods on a platform that generated almost $3 billion USD in revenues last year.

Budweiser

The Global 500 giant built their innovative TapWiser app on Realm. It allows bars & stores to quickly order new kegs & bottles directly from a mobile app, since most outlets don’t have a computer on site.

SAP

If you’re a Concur user, chances are you’ve used Realm already: expense reports & travel plans are managed in this app that serves over 20,000 clients and 30 million end-users.

Rite Aid

The Fortune 500 retail giant trusts Realm to securely store data for customers, via the EnvisionRx program.

Other notable users include: Amazon, eBay, Google, GoPro, Walmart, Adidas, Cisco, NBCUniversal, Nike, the NFL and many, many more.

What’s Next

We’d love your feedback on what we can improve, and are here to help you along the way on Stack Overflow and Twitter!

Get Started with Realm Java - or check out the source on GitHub
Get Started with Realm Objective-C - or check out the source on GitHub
Get Started with Realm Swift - or check out the source on GitHub
Get Started with Realm React Native - or check out the source on GitHub
Get Started with Realm Xamarin - or check out the source on GitHub

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

Read more

Realm Objective‑C & Swift 0.103 – Dropping Support For Older Versions, Plus Improvements

by /

We’re releasing version 0.103 of Realm Objective‑C and Realm Swift today, with a few minor breaking changes and improvements. Read on for more information.

Breaking Changes

  • All functionality deprecated in previous releases has been removed entirely.
  • Support for Xcode prior to 7.3 & Swift prior to 2.2 has been completely removed.
  • RLMResults/Results now become empty when a RLMArray/List or object they depend on is deleted, rather than throwing an exception when accessed.
  • Migrations are no longer run when deleteRealmIfMigrationNeeded is set, recreating the file instead.

Enhancements

  • Added invalidated properties to RLMResults/Results, RLMLinkingObjects/LinkingObjects, RealmCollectionType and AnyRealmCollection. These properties report whether the Realm the object is associated with has been invalidated.
  • Some NSErrors created by Realm now have more descriptive user info payloads.

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