Support

Language

Realm Blog

Are you headed to Google I/O? Join Realm in Mountain View and San Francisco for some I/O fun! Whether you have tickets to the conference or are just in town for the other events, we have something planned for you.

Women in Android Panel: Realm and San Francisco Android Developers are hosting a Panel discussion on the second night of the conference at Realm Headquarters (Details and registration below).

Google I/O Scavenger Hunt and Realm Swag: Can’t make it to San Francisco but still want in on the fun? Don’t worry, look for us at Shoreline on Wednesday before the Keynote. We will be handing out details about our Google I/O Scavenger Hunt and some fun Realm swag.

Afterwards: Stay and chat with our panelists, mix and mingle some more.

*IMPORTANT: Capacity for this event is limited. RSVPs are required to attend and will be FIRST COME FIRST SERVED for the first 150 people at the door by 6pm. RSVP ON EVENTBRITE

Panelists

Stacy Devino is the head of Mobile Apps for one of the fastest growing FinTech companies in the US. Prior to that she was the technical lead for Android Apps at Home Depot. Stacy has been doing this since Android 1.6 and has worked in embedded Android operating-system-level as well as hybrid and consumer applications.

Caren Chang studied Computer Science at UC Berkeley and has been around the Bay Area ever since. Previously she worked at companies such as Dreamworks and VSCO, and is currently helping build smart ovens at June. Her favorite part of Android development is working with custom views and animation.

Angella Derington is a seasoned Android developer with a passion for creating experiences that delight the user in their simplicity and polish. In the last few years, she has been busy working on the Android apps for major retailers. When not building apps, Angella keeps herself busy with her two kids, dog, and two cats!

Nicolette Yadegar is currently the Technical Lead for Support Engineering on Microsoft’s Yammer Android team. As Team Lead, she focuses on Performance and QA, while working on internal projects including upgrading/adding new libraries, adding fun features like GIF support, and refactoring efforts. Before that she worked at Microsoft on their IoT Innovation team and their Frameworks & Services team.

Britt Barak (Moderator) is co-leading Android Academy TLV which is one of the largest and most active Android communities out there. Britt is also leading the Women Techmakers Israel community. She is on a mission of sharing knowledge and inspiring others. You can find her public speaking, mentoring and blogging on Android development at .

This panel is presented by Realm, a platform to build reactive apps, realtime collaborative features, and offline-first experiences.

Delivering fast, responsive app experiences online and offline

A golfer’s game depends on good decisions with every shot. Performance data, captured and analyzed in realtime, can help players improve their skills mid-game and make better decisions throughout the course. As the field of connected sports gains momentum, Arccos Golf is using today’s innovative IoT and mobile technologies to re-invent one of the world’s oldest games.

The company’s innovative shot-tracking system pairs small, ultra-light golf club sensors with a mobile app and analytics platform. Using GPS and Bluetooth, Arccos automatically captures data on every shot, analyzes a player’s strengths, weaknesses, and trends, and delivers feedback through the mobile app in realtime. Such data-driven insights can dramatically improve a player’s ability to make the right decisions at every hole.

In order to deliver on their vision, Arccos needed to provide a fast, seamless user experience with zero disruption to the player’s golf routine. Their system had to handle significant data flows from sensor data capture and analytics processes, as well as from rendering detailed course maps and a rich UI—all in realtime. Because users expect apps to function wherever they are, the Arccos mobile application needed to work on remote golf courses where mobile connectivity may be unreliable.

Three different models for handling data

Originally, Arccos outsourced the development of an Android app that took a traditional approach. The app used RxJava and OrmLite, SQLite. However, the performance for this model was unacceptably low and the Arccos development team had to persist data as JSON blobs as a workaround. To translate data between models and keep it all in sync, the Arccos development team had to write a massive amount of code. This meant significant time spent debugging and maintaining code, which distracted the team from focusing on new development. Arccos users experienced frustratingly slow app performance, which inhibited their ability to get the most out of it. Arccos knew that they had to re-architect their system in order to make it more efficient and sustainable.

Unified data model on Realm

Arccos decided to explore a simplified data solution using Realm, and they started by building a proof of concept to evaluate this new approach. The development team was initially impressed with how quickly they could get Realm up and running — no lengthy boilerplate code or set up processes needed. More importantly, switching to Realm resulted in a significant increase in transaction speed.

“With Realm, we noticed a huge improvement in the loading time of one of our asset classes. What used to take 6 seconds, now takes about 20 milliseconds. The speed was impressive.”
- Muhammad Arafat, Android Team Lead, Arccos Golf

Arccos found that Realm’s reactive architecture enabled a fast, responsive user experience, regardless of network connectivity. In the golf course environment, offline usage is critical. The team was particularly happy with Realm’s support for offline-first use cases. Realm persists data locally on device, which enables users to access all app data while offline.

Realm’s single data model allowed Arccos to simplify their system architecture, streamline app code, and more easily improve stability. Because app data is stored as objects, the database didn’t “get in the way” and distract the team with tedious data translation tasks, making it much easier to implement a pure object model that worked well for their application. In addition, Realm only pulls into memory the parts of the object that you actually need or are actually touching. This effectively spreads the transaction time across user actions ensuring a seamless experience for the user.

“Re-architecting our app on Realm shrank our code base by about 35%, making it much easier for us to debug and maintain.”
- Colin Phillips, VP of Software, Arccos Golf

Using platform tools, such as the Realm Browser, the Arccos team found that they were able to discover and troubleshoot bugs much faster. The browser helped Arccos ensure that their objects were structured correctly, see the one-to-one mapping across objects in memory and the database, and quickly identify any issues.

Ultimately, migrating to Realm has been a game-changing decision for Arccos. Players now experience a highly responsive app that works well on a remote golf course. The development team can now move faster and spend more time building new ways to help players become better golfers.

This is really just the beginning — we’re now an official Microsoft partner, and are working on making the other Realm Platform editions available on Azure. And we’re on the same path with the other major cloud platforms as well, so stay tuned.

Getting Started on Azure

Sign into your Azure account (or create one), then click the green plus sign (+) on the left to get access to the Marketplace. Enter Realm in the search box and choose the result. You’ll be walked through Azure’s quick and pretty straightforward five-step process to get your server configured. The necessary ports for Realm — 9080 and 22 — are preset. Other than naming things and setting up SSH, you can pretty much accept all the defaults.

Following step five, it takes a minute or two for deployment, after which you’ll see the details of your new server, including the IP address. Open a new tab, copy that into the address bar, add :9080 to the end, and hit enter — you’ll see the Create Admin User panel for your shiny new Realm Object Server instance running Azure. Success! Now you are ready to start exploring the platform — start with one of our fun demo apps, like Realm Pop (realtime gameplay), Realm Draw (realtime collaboration), or Realm Tasks (realtime task management).

You’ll find more documentation for using Realm’s Permissions APIs in the Access Control section of our docs.

These APIs require any edition of the Realm Object Server 1.1.0 or later.

Faster Reconnects

This release detects changes in connectivity status via the Reachability framework to instantly attempt a reconnection with the object server if the connection was not sustained.

Previously, the time before reconnection occurred was dependent on how long it had been since the connection was lost due to our exponential backoff reconnection algorithm.

Password Change

Users can now change their passwords using the -[RLMSyncUser changePassword:completion:] API if using Realm’s ‘password’ authentication provider. This API requires any edition of the Realm Object Server 1.4.0 or later.

Other Enhancements

{RLM}SyncConfiguration now has an enableSSLValidation property (and default parameter in the Swift initializer) to allow SSL validation to be specified on a per-server basis.

Transactions between a synced Realm and a Realm Object Server can now exceed 16 MB in size.

This week, James is joined by friend of the show Adam Fish, Product Manager at Realm, who introduces us to the cross-platform mobile reactive database, Realm for .NET. Realm offers developers a crazy fast, mobile optimized, easy to use, open source, and totally free database. Adam walks us through setting up your first Realm database and then expands on it to create an offline-first, real-time, and reactive mobile app leveraging the Realm Mobile Platform. You don’t want to miss this episode!

Intro (0:00)

My name’s Adam Fish, I’m the Senior Director of Product at Realm. I’ve been with the company for about two years now. Realm is a database company, and is about five years old. It got started as a typical Silicon Valley start-up. The founders are Danish and came over from Copenhagen, raised some capital, and built the database from scratch.

During the first three years, it was a high-speed, in-memory, server-based database. We quickly realized, with its unique capabilities coupled with the growth of mobile, that there was a great opportunity to basically build a replacement for SQLite or any of the derivatives. Two years ago, we launched it for iOS, and since then we’ve added Android, Xamarin, .NET support, and React Native. It’s really designed to be a cross-platform, and easy to use mobile database.

What is Realm? (2:19)

It’s pretty common to forget that the only database that anyone uses on mobile is SQLite. There’s always different wrappers that people put around it, Core Data being a major one for the iOS platform, but at the core, it’s SQLite.

With Realm, the biggest argument to build something new was that at the end of the day, when you’re building mobile apps, you’re working with objects. There’s always this mismatch between the object layer and the SQL layer. A lot of effort and Core Data goes into trying to manage that, with a ORM, but you’ve always got some level of mismatch than can happen. With Realm, we decided to build it from the ground up as something new.

At the core level it is a table interface, but the actual columns can link to other tables, so it inherently supports links. You don’t have that actual mismatch. We’re able to then provide an object interface in whatever the native language is that you’re using for the platform, and it just becomes a very fluid development experience.

Coupled with that, there’s been a real focus on performance. It’s a column-based database, so it can have really high performance and it uses memory mapping. You’re basically interacting with the data directly on disk and there’s no in-memory copying that’s happening.

Before I worked at Realm, I was working on my own start-up, we had an iOS app, and we were spending an inordinate amount of time fighting with Core Data; your typical threading issues and things that you’ll run into. When it launched, it was the simplicity of Realm that attracted me. I remember going to the website, and I saw the code snippets, and thought, “Aw, yes, that makes a ton of sense.”

The moment you start playing with it and you realize that not only is the interface really easy, but I’m not having to pay any performance penalty for that ease of use. It just became a no-brainer. We re-wrote the whole app using Realm. We started to do some really cool stuff, and contributed some open source projects that use Realm. I became an avid user, and the company ended up saying, “Why don’t you come and join us?”

Since then, speaking with developers, they echo the same thing. It’s the ease of use and performance. It’s the two that come hand in hand that really sells it.

Every month, there’s more Fortune 1000, Fortune 500 companies, and major brands that are moving to Realm and using it in their applications on all the different platforms. It has really taken off. It is fully open source.

During the first three years of the company, when it was more server-oriented, the core database was written in C++. When we first launched, just the bindings that wrapped that C++ layer into the native language of the platform were open source. Last summer, we open sourced the core. The whole stack of the actual database is fully open source on GitHub. Coupled with the open source nature and the fact that it’s been five years since it’s been built, we think it really is battle-tested at this point.

I have to hand it to a lot of the developers on our team, I became a better developer just watching how the Cocoa team at Realm had actually built that version of it. With a lot of the Objective-C run time and stuff, they do some really amazing work. Being able to watch that in real time, it’s amazing as a developer.

Realm and Cross-Platform (7:48)

The easiest place to get started with Realm is realm.io, that’s the number one place. You can just jump right in. We try to get you into the code, right on the homepage, so you can see a little bit about how you would use the database and some of the newer features that we recently released. If you go over to the docs, you dive into the platform that you’re looking for. If you look on the Xamarin docs, there’s a quick getting started. The package is available through NuGet.

The code is on GitHub. There is Xamarin iOS, Xamarin Android, and Win 32 support. We’re trying to work on spreading that over time to all the other platforms.

While there are some edges of the SDKs that are platform specific, the general concept of how you work with Realm objects and write transactions, is all very similar. Someone that is fluent in .Net could look at a Java code snippet and immediately adjust it.

Sample App(9:45)

There is a sample app that we include in the repo called Quick Journal. It’s basically a task tracker app. The first thing really to dive into is that looking at the data model of this application, we are creating an object called a JournalEntry. That’s what’s going to be represented in the table.

When you work with Realm, this is kind of like the key starting point of understanding how Realm works. You sub-class a Realm object, and that sub-class is actually the definition of your data model or schema. With the JournalEntry, we’ve got a string property for Title, another for BodyText, and then we’re demonstrating linking to another object, where we have another Realm object called EntryMetadata.

This is the nice part about how Realm works under the hood; at the core level those links are represented just like a reference. What’s really cool is that if you actually build an app that has a really complex object graph, when you query and you’re working with these Realm objects, you don’t actually have to pull all those objects into memory. You can actually traverse the object graph lazily. It does it for you. As you go to new objects, you basically don’t have to use as much memory. There’s no foreign key look-ups or anything. It is just working with almost totally native objects.

If you create a Realm JournalEntry object initially, its state is unmanaged. It’s basically just an in-memory object. It becomes managed when you actually add it to the Realm. We can show what that looks like, but that’s what isManaged is demonstrating.

The Realm is actually a single file. You can actually introspect the file. We’ve got a little browser application. It’s a single Realm file that is the database, so when you take an unmanaged object, and you add it, it’s going to write that and persist it on disk as well.

Transactions (13:41)

The view looks like a standard XAML. The add entry command is what we’re binding to. In the view model there is nothing Realm specific in that. In the application, if I click “add,” I can just give my journal entry an ID. If we look at the view model code, when I actually am adding that journal entry into the Realm, this is what it looks like.

The key aspect of working with Realm objects is that every interaction or write that you’re doing with Realm, or any change to the object, needs to be done in a write transaction. There is a very big secondary benefit of having this transaction-based model, which is you know the database is basically acid compliant, and it also is crash-safe.

Acid compliant means that you have a stable view of the database no matter which thread you’re on. It’s just basically a number of different properties the database has that prevents it from having corruption.

The database has what’s called a multi-version concurrency control system. Basically, what happens is the database in itself is essentially just a B-tree, if you want to visualize it. When you create a new transaction, there’s a new root of the tree that’s added, but any other thread that’s doing reads, because the writes are not blocked by reads, continues to look at all the data that’s in the previous root. You can add all your changes in that transaction, and then it’s actually going to write it down to the disk, and call an F-sync command, so that it is actually fully on the disk.

Only after that has happened, do we advance to the new root of the tree. The key point is that, if suddenly your phone died, or something happened and that other transaction was partially complete, the original root of the tree is still there, so you’re never going to get corrupt data. It’s a little in the weeds, but using write transactions actually is very beneficial in terms of the durability of the database itself.

The _realm is how you actually interact with the database itself. The thing with Realm is that it is all accessors, as I would call it. Whether you’re working with the database as a whole, which is what this Realm.GetInstance is,

_realm = Realm.GetInstance();

or you’re working with any sort of Realm object that you’ve gotten from the database, all of those are thread-specific. If I was on a background thread, I would also call Realm.GetInstance, and I would have an object specific for that thread. You never want to pass Realm objects across threads.

We actually do offer the capabilities to do that, so you can. There are ways to pass objects across threads, but you can’t just take an object and directly move it across.

When you actually commit the transaction, and it finishes, then it’s written to the disk.

The transaction gives you the, in the acid, the atomicity of being able to say that these two changes need to always be applied together. That’s another benefit of having a transaction system. We would recommend to use larger transactions than to do a bunch of really small ones. It depends on the circumstance. If you’re looping over, we’d say put the loop in the transaction itself.

Querying (20:16)

It’s pretty straightforward interaction in this application. There’s a lot of other things that are more hidden here, because this is a forms-based application. The querying that’s happening in terms of reading the data is a little bit more hidden from view.

On the JournalEntryDetails page, when you’re typing, you are just writing to the Realm object, setting it right on the property itself. Then you save, and this is where the commit happens.

You created the entry, and you passed that entry to this page. You’re doing live data binding to that entry, and then when you hit save, then it commits it. You’re not setting any properties, you’re just typing to it, and it just knows.

That’s all from the binding itself. We tap into that automatically. That’s going to be setting it for you, and so as you commit it, that’s when it’s actually going to hit the disk. When you’re using Xamarin forms, the data binding is plugged into automatically.

We actually support a number of different abilities to listen for changes. If you’re not using a form-based application, we have a number of different APIs where you can basically query the database.

You could query all the person objects in the Realm, and then, whenever that query changes, it tells you. We can even pass in a changes object that’ll say, “Here are the ones that have been inserted, deleted, or modified.”

If you’re working with an iOS or Android app directly, you can pass this into list view or a UI table view to do the animations, if you’re doing this more manually. We also support object notifications, so you can get when properties specifically change.

This is what’s beneath the hood with Xamarin forms, which is doing this automatically for you, but if you’re not using that, you can still tap into that same sort of reactive architecture. Once you’re done completing the transaction, you commit it, and there’s nothing you need to do.

We have a complex query capability. We tap in and use link with that, so you can use a similar link query syntax to work with the database. You can sort objects and use a number of different query capabilities.

The really interesting thing about this, is this lazy loading aspect of the database. When you perform a query, you’re not having to actually pull all those objects into memory. If you imagine you had 10,000 objects that match your query, it does not have to actually move all those into memory. Instead, only when you start accessing the individual objects in the query, do you actually start interacting with them. The memory performance for applications that have tons of data is much lower than you would find with SQLite.

When you perform the entries = _realm.All command, it’s not having to move all those objects into memory. Instead, if you had the screen where the objects were much larger than what could fit on the screen, as you’re scrolling and trying to call out to get the data, that’s when it’s actually interacting with it, so it’s extremely efficient.

We don’t support limit, because it’s irrelevant. You don’t have to paginate when working with this.

The vast majority of times, you can do it all on the UI thread. Now I know that’s kind of a very controversial statement. We’ve designed the performance with the memory mapping, lazy loading, and all these capabilities, that it really can be used on the main thread. Now there’s always going to be an edge case. You can very easily switch to background thread, get a new instance of the Realm for that thread, and work with the objects on the background thread. Then utilizing those notification capabilities, if you say, “were doing some sort of background synchronization on another thread”, and you make changes, your UI thread can subscribe to those notifications as those changes come in and react to it.

It’s a very simple model in terms of being able to listen for changes that are happening across threads. Even more interestingly, this works across processes. If you have an iOS, widget of some sort, where you’re using one of the notifications, original to apple watch app, you have different processes. Another process can be working with the Realm, making changes, and the other process can actually listen for those changes.

Realm Mobile Platform (28:38)

There was a master plan with Realm all along, and it builds off of this idea that the Realm objects are live and auto-updating. As you’re making changes, they’re being synchronized across threads. What we wanted to do was basically say, imagine it’s not the change coming from another thread that’s updating the object, what if that change is coming from another device, or a server? For the past couple years, we’ve been working on what is called the Realm Mobile Platform, and it includes a Linux-based application called the Realm Objects Server that automatically synchronizes changes. The really slick thing is, you pretty much already know how to use it if you know how to use Realm. There’s not much else more to it in terms of the client experience.

Every time you make changes to the local database, they get persisted locally on disk, and then the change itself is sent to the object server and it handles sending it wherever else it needs to go.

It is extremely low-latency. We aren’t sending the state of objects around, which is like traditional REST API, requesting the json. Instead, because we control the whole stack, we know the specific changes that have actually occurred, and we send the operations.

It’s designed to also be offline first, because from a client mobile developer perspective, your source of truth is the database on disk. You’re making changes to it, and then asynchronously, those changes get sent. On the server application, we used what’s called operational transformation. It’s basically a way to make sure that all the changes get ordered correctly regardless of whether the network has sent them in order.

Realm Browser (31:06)

There is another app included that you can play with for the Realm Mobile Platform. It’s another task app. You just need Realm and Realm database. The key difference is there is a name space sync that includes a number of different APIs. If you don’t want to use the mobile platform if you’re not using the server, you don’t have to; it doesn’t change the database itself. It’s just other APIs that you can tap into if you want to use it.

We put a little more effort into the UI for this app, but it’s a task application where you can have lists, and then you can click in and add different tasks here. It’s also using Xamarin forms.

The key thing to show off is that, we have this mac application. We are working on a cross platform version of this, but today the Realm browser is just a mac application. It’s really cool because you can go in here and you can open up, local Realm database files. You can use this even on device, when you’re developing, you can go get the Realm file off the device and explore it if you need to.

If you download the zip file, the package for the Realm mobile platform, we have a free version, which is called the developer edition. You can run it locally on your mac, which is mainly just for debugging. If you’re going to use it for production, there’s a whole Linux installation. I’ve got it running just a single command. You start it up, and it runs in the terminal. After you start it up, it’ll open the dashboard. It’s a very primitive and basic dashboard at the moment.

You can see all the synchronized Realms that you’re working with. You can see all the users that are actually in the server itself, and even check out the logs.

I’ve got the server running locally, and so I have connected in the sample app, Realm task. I’ve logged into this local server. The synchronized Realm I’m connecting to is connecting to the local host and opening up the Realm file.

Beneath the hood, each application has its own copy of the data, and so the browser has its own copy of the Realm. The simulator has its own copy of the Realm, and the server, running in the background, is going to automatically synchronize the changes. If I make a change, you’re immediately going to see it. I can then undo the change, and call this task two.

The nice part about this, because it is a Xamarin form app, it is basically doing implicit transactions. Every time there is a property update, it is tapping into the inner workings of the data binding mechanisms to be able to create a write transaction on every small change, and so that’s how you’re seeing, it.

Specific character-by-character changes happening.

As a developer, you’re still just writing to make changes to a Realm object. Beneath the hood is the async networking that’s just doing everything for you. That’s really the productivity benefit. I’d rather not have to write json parsing and making network requests and handling any sort of the error scenarios. I just want to work with synchronous local APIs, and make the UI beautiful or build the unique capabilities in the app, rather than all the data handling that, we continually have to rewrite.

An individual Realm is the encapsulation of the data being synced. The unique nature is that, a Realm itself is very lightweight. In the previous app, we had the default Realm and we were just putting all the data into a single Realm. With the Realm mobile platform, we recommend thinking about it a little differently. You might have several different Realms with different datasets. That’s how you can synchronize data at different times. One part of the app, like the homework feature of the app might only use the homework Realm if the user goes to that area, and if not, it’s not actually doing any sort of synchronization.

Authentication (38:59)

The permissions for how you work with the platform is all around Realm users. The object server has built-in authentication for username and passwords. It also supports a number of federated or external identity systems, and so, we’ve recently added active directory support.

To actually go and get it implemented, you have to do a couple of things. When you start the server, there’s a configuration file. There’s a section called providers, and this is where you can enable the supported third-party providers. For example I’ve got the Azure provider with my attendant ID, because I’m using the Azure active directory cloud offering.

You have to set your client ID, and your redirect, but basically you create a credentials object, and there’s various different methods that we support. You can create a credential that’s a Facebook credential, a Google credential, or Azure active directory credential, etc.

We’re basically using the Azure STK to go out and get the access token, and then once the client has the access token, it passes it into Realm’s APIs to send that access token to the Realm server and say, “This is my identity through Azure, please verify it.” If it’s verified, then you become a Realm user.

If you just want a username and password type login, its done for you automatically. Instead of creating, a credential where you’re using Azure, you’d be just creating a credential with the username and password. There’s register and login methods associated with it.

Conclusion (41:45)

The number one place is to go for information is the website. You basically have two options. You can go download it locally on your mac, and get it up and running really quickly. Alternatively, you can go over to the Linux install. We support a couple different flavors of Linux: Red Hat, Enterprise, CentOS, and Ubuntu. We also have AWS/AMIs available, but the easiest way to do it is to get your Linux VM up and running, and then we just go through a couple of.

I think that sums it up. If you’ve got any questions, we are very active with support. You can go to the GitHub repo, and file an issue if you have any sort of problems that arise. Our documentation is all on realm.io, that’s just the best place to start if you’re interested.

RealmPop is a simple retro multi-player game we developed for our Realm World Tour. It lets iPhone, iPad, and Android devices connect to a Realm Object Server instance and play against each other, and we’ve made it open source so you can download it and take it for a spin yourself!

We tried to find a balance between a very simple demo that would be understandable even to an audience who have never touched Realm before, and an engaging project that both keeps people excited and shows a wide range of Realm features.

Great as the event demo was (just ask all the people who volunteered to play the game live on stage) we could not add too many features to it, because we were demoing everything live (we’re only human after all :)

Hence: RealmPop 1.1!

Today we are releasing an update to RealmPop to address a few issues we discovered during the tour, and to add a more-involved server-side component where the real power of the Realm Mobile Platform lays.

The updated project shows you how to develop part of the game’s logic on the server with the help of our Node.js SDK and compliment the functionality on the mobile clients. We’ve sprinkled comments all around the code too, you’re welcome :)

We’ve updated RealmPop’s README with detailed instructions on how to:

install & run Realm Mobile Platform

configure & run the RealmPop server app

and run the iOS and Android games

So what are you waiting for? Head to the repo https://github.com/realm/RealmPop right now, follow the README and have the RealmPop server and mobile apps running in no time!

PS: What would you like to see next in RealmPop? Server bots? React Native? More advanced multiplayer features? Let us know on twitter and tag with #realmpop.

We’re releasing version 2.6 of Realm Objective‑C and Realm Swift today. In this release, we’re introducing powerful new APIs to asynchronously open Realms, retrieve the administrative status of Sync Users, compact Realms on first access and applying a few bug fixes to keep your apps running strong.

Asynchronously Open Realms

This release introduces an API to asynchronously open a Realm and deliver it to a block on a given queue.

This performs all work needed to get the Realm to a usable state (such as running potentially time-consuming migrations) on a background thread before dispatching to the given queue. For example:

In addition, synchronized Realms wait for all remote content available at the time the operation began to be downloaded and available locally.

The default behavior for synchronized Realms is to provide instant access, even when offline, and to incrementally sync data from the Realm Object Server. However, some apps benefit from having the latest state available before presenting it in the UI or performing some operation. For these situations, you may use the asyncOpen method to be vended a Realm only when it has been completely downloaded. For example:

letconfig=Realm.Configuration(syncConfiguration:SyncConfiguration(user:user,realmURL:realmURL))Realm.asyncOpen(configuration:config){realm,errorinifletrealm=realm{// Realm successfully opened, with all remote data available}elseifleterror=error{// Handle error that occurred while opening or downloading the contents of the Realm.}}

Sync User isAdmin property

{RLM}SyncUser now has an isAdmin property indicating whether the user is a Realm Object Server administrator.

Exposing this information makes it easier for you to write code that can manipulate arbitrary synchronized Realms since you can authoritatively determine if a user has administrative access to all Realms on a Realm Object Server instance.

For example:

SyncUser.logIn(with:.usernamePassword(username:"admin",password:"💯secure"),server:serverURL){user,errorinifletuser=user{// can now open a synchronized Realm with this user// true if the user is an administrator on the ROS instanceuser.isAdmin==true}elseifleterror=error{// handle error}}

Compact On Launch

Realm’s architecture means that file sizes are always larger than the latest state of the data it contains. See our docs on Threading for some of the reasons why this architecture enables some of Realm’s great performance, concurrency and safety advantages.

Additionally, to avoid making expensive system calls to expand the size of a file very frequently, Realm files generally aren’t shrunk at runtime, instead growing by distinct size increments, and new data being written within the free space tracked inside the file.

However, there are cases in which a significant portion of a Realm file is comprised of free space. So this release adds a shouldCompactOnLaunch block property to a Realm’s configuration object to determine if the Realm should be compacted before being returned. For example:

letconfig=Realm.Configuration(shouldCompactOnLaunch:{totalBytes,usedBytesin// totalBytes refers to the size of the file on disk in bytes (data + free space)// usedBytes refers to the number of bytes used by data in the file// Compact if the file is over 100MB in size and less than 50% 'used'letoneHundredMB=100*1024*1024return(totalBytes>oneHundredMB)&&(Double(usedBytes)/Double(totalBytes))<0.5})do{// Realm is compacted on the first open if the configuration block conditions were met.letrealm=tryRealm(configuration:config)}catch{// handle error compacting or opening Realm}

Under the hood, the compaction operation reads the entire contents of the Realm file, rewrites it to a new file at a different location, then replaces the original file. Depending on the amount of data in a file, this may be an expensive operation.

We encourage you to experiment with the numbers to identify a good balance between performing the compaction too often and letting Realm files grow too large.

Finally, if another process is accessing the Realm, compaction will be skipped even if the configuration block’s conditions were met. That’s because compaction cannot be safely performed while a Realm is being accessed.

Setting a shouldCompactOnLaunch block is not supported for synchronized Realms. This is because compaction doesn’t preserve transaction logs, which must be kept for synchronization.

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 3.1 of Realm Java today, and with it introducing better backup recovery for synchronized Realms, fine-grained object notifications for all Realms, and initial support for reverse relationships. Read on for all the details.

Fine-grained Object Notifications

In Realm Java 3.0, we released fine-grained collection notifications that made it possible to get detailed information about changes to collections. In 3.1, we extend that capability to single object notifications as well with the new RealmObjectChangeListener interface and the ObjectChangeSet class.

Personp=realm.where(Person.class).findFirst();p.addChangeListener(newRealmObjectChangeListener<Person>(){@OverridepublicvoidonChange(Personperson,ObjectChangeSetchangeSet){if(changeSet.isDeleted()){hide();// Object was deleted}else{// Use information about which fields changed to only update part of the UIif(changeSet.isFieldChanged("name")){updateName(person.getName());}}}});

In past releases, single object notifications have had a lot of false positives, in the sense that the listener would trigger even though nothing had changed. This has also been fixed in 3.1, so now single object notifications, fine-grained or not, should only trigger if something in the object changed.

Better Backup Recovery

When your servers go down, you need a plan to recover. That’s why the Realm Mobile Platform has offered the ability to backup your data for a few months now.
Under normal conditions, Realm’s synchronization engine works by transferring just the specific operations. When the Realm Object Server confirms the receipt of new operations, the local logs are cleaned up. This helps keep your app’s disk usage small and Realm blazing fast ⚡️.

Furthermore, because Realm is an offline-first database, if your Realm Object Server is down for whatever reason, all your local data stays available.

However, if you need to recover from a backup on your server, your clients will receive a “client reset” error via the sessions error handler. Note that you may continue to use the local Realm as you normally would, but that any subsequent changes, or changes made after the last backup point, will be lost.

Once you receive a “client reset” error, you could inform the user about the situation, stop accessing the Realm and redownload the Realm from the server at the latest backed up version. The ClientResetRequiredError class contains information and methods you can call for manually cleaning up the previous local version of the Realm.

If you choose to not handle the client reset error immediately, the next time your app launches, the previous local version of the Realm will be deleted and redownloaded from the server at the latest backed up version automatically on first access.

finalSyncConfigurationconfig=newSyncConfiguration.Builder(user,url).errorHandler(newSyncSession.ErrorHandler(){@OverridepublicvoidonError(SyncSessionsession,ObjectServerErrorerror){if(error.getErrorCode()==ErrorCode.CLIENT_RESET){ClientResetRequiredErrorerr=(ClientResetRequiredError)error;closeRealm();err.executeClientReset();// Manually do the reseterr.getBackupFile();// Reference to backed up file}else{// Handle other errors}}}).build();

Inverse Relationships (BETA)

In Realm relationships between objects are bidirectional, which means that if you have a reference from Person to his/her Dog, then Realm automatically establishes a relationship in the other direction as well, and will automatically maintain it.

This inverse relationship is normally hidden in your model classes, but today we are shipping a new @LinkingObjects annotation that can make that inverse relationship visible so you can navigate through it.

In order to define an inverse relationship you need to do the following:

Add a RealmResults field with the generic type of the parent object.
The field must be final. Realm will automatically fill it out for managed objects. Un-managed objects do not support inverse relationships.
Add the @LinkingObjects annotation with the name of the field on the parent object that points to the model class defining the inverse relationship.

Take this example:

publicclassPersonextendsRealmObject{publicStringname;publicintage;publicDogdog;}publicclassDogextendsRealmObject{publicStringname;@LinkingObjects("dog")publicfinalRealmResults<Person>owners=null;}// Use the inverse relationship Dogdog=realm.where(Dog.class).findFirst();dog.owners.size();// Find number of ownersdog.owners.first();// Get a reference to the owner of the dog

The true power of reverse relationships will come when you can query across the inverse relationship and we are working hard on adding that for the next release.

Because implementation of queries has not yet been completed, we have marked the @LinkingObjects annotation as @Beta and would love your feedback on this feature.

File format upgrade

In 3.1 the internal Realm file format has been changed. Older Realm files will automatically be upgraded when opened, but doing so means that they no longer can be read by older versions of Realm.

The first leg of the Realm World Tour just wrapped up, and thanks to the tremendous energy of everyone in the Realm community who participated, it was amazing…check out the highlights!

We put in thousands of miles, visiting 23 different cities over the course of 2 months, meeting thousands of you face to face, and getting you started building apps with the Realm Platform. We laughed, we ate pizza, we tested code, we played games, and best of all we got to hear from you about what you are doing with Realm! We had so much fun, we’ve already started to thinking about what’s next (see below).

We couldn’t have done any of this without the help of our fantastic world tour hosts who opened up their offices, event spaces, and restaurant recommendations to us! A big thanks to all the local companies, hosts, and meetups for helping us make the tour happen!

A few special shout-outs to:

Q42 in Amsterdam for the most amusing host space, which includes a slide that tweets a video of you. https://twitter.com/q42glijbaan

Paris hosted by Deezer for the fastest Realm Pop player, who won live on stage with a time of 1.4 seconds!

Chicago hosted by Trunk Club for having the most awesome office space, and delicious beers on tap!

Announcing the next leg of the Realm World Tour

Bringing the Realm Platform message to 23 cities was so much fun, we want to bring it to a few more. So we’ve started to plan the next leg of the Tour, and we need your help: If you’d like us to come your way, tweet us @Realm with hashtag #RealmWorldTour and hashtag of your city (e.g., #SanFrancisco). Then get the rest of the devs in your city who want to attend Realm Tour to do the same. We definitely want to prioritize the cities where we know we’ll get a great turnout.

Stay in the loop on Realm events and more

If you’re not already on the Realm list, add your email here. We’ll keep you up-to-date on Realm events, content, and product news.

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. Old files can still be opened and files open in read-only mode will not be modified. Please be careful about shipping updates to your existing apps!

We’re releasing version 2.5 of Realm Objective‑C and Realm Swift today. In this release, we’re empowering queries with support for diacritic-insensitive string search, adding the ability to compare nested objects against NULL and applying a large number of bug fixes to keep your apps running strong.

We’re also now producing Swift binaries for Swift 3.0, 3.0.1, 3.0.2 and 3.1.

If using synchronized Realms, the Realm Object Server must be running version 1.3.0 or later.

Diacritic-Insensitive String Queries

You may now use the [d] modifier on string comparison operators to perform diacritic-insensitive comparisons. This modifier can even be combined with the case insensitive modifier ([c]).

For example:

==[d] 'u' will match on ü

BEGINSWITH[d] 'e' will match on étoile

CONTAINS[d] 'n' will match on Piñata

ENDSWITH[d] 's' will match on diaçrïtičş

ENDSWITH[cd] 'É' will match on café

Note that this cannot be applied to LIKE comparisons.

Multi-level object equality comparisons against NULL

You may now query for multi-level object equality comparisons against NULL. For example:

Fix an assertion failure when an observed RLMArray/List is deleted after being modified.

A Note About Xcode 8.3

We typically produce Objective‑C binaries using the latest stable Xcode version, which as of this week is Xcode 8.3. However, we’ve discovered (rdar://31302382) that Xcode 8.3 produces binaries with bitcode slices about four times as large as previous Xcode versions! This brings the Realm Objective-C framework for iOS from its usual 55MB to about 158MB! So we’ve decided to continue building the Objective-C framework using Xcode 8.2. You may choose to build Realm Objective-C from source using Xcode 8.3, and your end users won’t be affected because bitcode is stripped from the binaries when apps are served from the App Store.

We’re making it easier than ever to integrate your existing systems with a modern mobile app, by introducing Custom Authentication on the Realm Mobile Platform. With a few lines of JavaScript, you can bring your own authentication to Realm, allowing your users can log in with their existing credentials and begin using any app built on the Realm Mobile Platform. Using Custom Authentication, you’ll be able to build modern mobile apps with single-sign on (SSO) capabilities, and you can even mobilize your whole legacy backend by integrating our new data connector API, so that your users get access to the data and capabilities they expect.

Legacy systems put you in a double bind when you want to build a new, useful mobile app. If you use your existing backends, it’s likely to be incredibly hard to build the new features your users demand — features that require streaming lots of data from many sources, which tend to overwhelm APIs built for a calmer web. But migrating your API to a more developer-friendly platform is likely to be even harder, exposing you to new security risks in untested authentication APIs, and forcing you to solve problems that you thought you already put behind you, this time in a new language and framework.

Wouldn’t it be great to keep the hard work you put into your API, while also getting all the modern development tools that make it easier to build better apps? That’s what bring-your-own authentication does for the Realm Mobile Platform. You get to integrate Realm with your trusted legacy authentication APIs, so that your users simply bring their username and password (or any other tokens or credentials) to your mobile app, and the Realm Mobile Platform handles the work of authenticating them against your existing API. Your developers don’t just avoid rewriting all their auth code: they also get realtime data sync, offline-first capabilities, and enterprise-grade data connectors for your existing databases and backends — all benefits that you get from building your app on the Realm Mobile Platform.

Here’s what it looks like in practice: you just write one short JavaScript file, then add a line to your configuration.yml file:

module.exports = function(deps) {
return class FooAuthProvider extends deps.BaseAuthProvider {
// This is used by the ROS when it loads the available
// authentication providers. This function is required.
static get name() {
return 'custom/fooauth';
}
// This is used by ROS when it parses the configuration
// file, to ensure that required default options are
// available. This function is optional.
static get defaultOptions() {
return {
auth_server: 'https://my.auth.server.example',
}
}
constructor(name, options, requestPromise) {
super(name, options, requestPromise);
// Here you can set your instance variables as usual
this.httpMethod = 'GET';
}
};
}

Now we get to the substance of the authentication provider, where we’ll make a request to your authentication API using the credentials that the user provided:

verifyIdentifier(req) {
// The token submitted by the client
const token = req.body.data;
// The client SDKs also support sending additional information
// in the form of a map/dictionary. This is accessible through
// the `req.body.user_info` key.
// The information required to reach your API server that can
// validate the token. Obviously, this assumes a REST-like API.
// Please note that `this.options` comes from the configuration file or
// `defaultOptions()` method defined above. Similarly, `this.httpMethod` is
// an instance variable defined in the constructor above.
const httpOptions = {
uri: `${this.options.authServer}/api/auth?token=${token}`,
method: this.httpMethod,
json: true,
};
return this.request(httpOptions)
.catch((err) => {
// Please see src/node/services/problem/http_problem.js
// for other error cases
throw new problem.HttpProblem.Unauthorized({
detail: `Something bad happened: ${err.toString()}`,
});
})
.then((result) => {
// This userID has to be unique, and will be used to either
// - create a user in the ROS
// - login the user, if it already exists
return result.userID;
});
}

By combining easy authentication with the data connector API, you’ll also be able to connect your apps to the data stored behind your legacy systems. Whether your API is as old as SOAP or just as request-driven as REST, the Realm Mobile Platform’s data connector API will give your users real-time, streaming access to their data they need, and your developers get to use the modern, reactive features of the Realm Mobile Database. You’ll be able to build great app experiences quickly, without trying to teach your older, legacy systems the new tricks they’d need to deal with the scale demands of mobile apps.

PostgreSQL is one of the most powerful and popular databases in use today, and is increasingly used for systems of record at all types of organizations. This works well for many use cases, but things get difficult when you try to build a modern, reactive app connected to your Postgres database. Postgres is fast, but it’s just not designed for realtime, reactive mobile apps.

Today we’re excited to introduce a solution: Realm’s new PostgreSQL Data Connector. This new connector creates a simple two-way bridge between Postgres and the Realm Mobile Platform, effectively making Postgres realtime for mobile apps. Data flows reliably and in a fault-tolerant manner between Postgres and the Realm Platform, which then handles realtime sync with your mobile apps automatically. This means changes made on mobile clients are automatically reflected back to your Postgres database in realtime, and data changes made in Postgres sync in realtime with client-side databases. You can now easily make truly reactive mobile apps with PostgreSQL and Realm.

Realm Mobile Platform as an alternative to REST APIs

The Realm Mobile Platform replaces traditional methods of using REST APIs to get data in and out of backend systems for use in a mobile context. Our automatic realtime sync service efficiently syncs only what has changed in the data model without the need for manual data requests or bandwidth-hogging polling. Realm automatically handles the realtime sync of your native objects—without the need for JSON—between clients and the Realm Object Server (the server-side component of the Realm Mobile Platform). The Realm Object Server can then provide the API integration point between your mobile application and PostgreSQL database to consolidate API management in the backend, where network issues are not a concern. This architecture reduces the number of API calls that each device must make and reduces the need for complex idempotent APIs that can handle unreliable network connectivity.

PostgreSQL Data Connector Demo

Here’s a video to show you an example of how we can link Postgres and Realm Mobile Platform:

Using sample data from a fictional DVD Rental company, we’re able to modify inventory levels via a mobile app or within Postgres and see those changes sync in realtime. It’s a simple example of how Realm can dramatically simplify making Postgres realtime for your applications.

We’re excited to show you how Realm can work for you in your environment. You can visit GitHub for the code and an in-depth overview of how to connect the Realm Mobile Platform and PostgreSQL to create reactive, realtime mobile applications with data stored in PostgreSQL.

JavaScript is probably the hardest working programming language in the world these days, and at Realm, we’re big fans. We love it because it fits great with Realm’s reactive architecture, and because JavaScript is virtually omnipresent. We’ve made it a key part of our platform, so that any developer with JS skills can use Realm. We started by shipping support for the Realm Mobile Database to React Native, and then we brought Realm to Node.js on Linux and macOS, which helps power the Realm Mobile Platform. And today we’re happy to announce Node.js support for Windows, meaning that you can use Realm wherever you can run JavaScript.

Realm now supports not only React Native, but also Node.js on Windows, Linux and macOS. Just like with Realm on mobile, you get all the advantages of the Realm Mobile Database — enabling you to easily and performantly persist any data you need to build your app. We’re also hard at work building support for the Realm Mobile Platform on Win32, so that you’ll be able to sync data with ease and build exciting real-time, collaborative apps using JavaScript.

Realm isn’t just easier to use. It also pairs with JavaScript’s advantages to enable better app experiences. Realm’s reactive principles mean data is automatically refreshed as it changes, making it fit beautifully in an event-driven architecture. It’s also cross-platform, so that you can take advantage of JavaScript’s enormous reach in order to deliver apps to your customers, no matter what devices they use. And finally, our universal support for Node.js means you can even use it for server-side use cases — like using Realm and Node.js to do interprocess communication on a webserver.

We’re making it easier to build the coolest, newest, best apps, on every platform, on any device. Today, we’ve taken another big leap in our journey to being a truly universal data platform, and we can’t wait to see what you build with it. Jump into the Realm JS documentation to get started with the Realm Mobile Database.

Today we’re pleased to introduce a new method of client authentication with Azure Active Directory for our community of .NET developers using the Realm Mobile Platform. Now organizations can create reactive apps that work with Microsoft App Service Authentication / Authorization for simplified sign on and identity management.

Setting up Azure Active Directory

Each Azure account has a default AD instance pre-created. For the purposes of this post, we’ll use that one,
but you can easily create a separate one by following a tutorial similar to this one.

Once you have the directory setup, create a new user by clicking Add a User in the Quick tasks pane:

Setting up the Application

To authenticate on the device, we’ll need to setup an Application. Go to App registrations and press Add:

Specify Name, and set Application Type to Native. The Redirect URI will be used by the client library
to identify when the login flow has completed, so it has to be a valid Url, but doesn’t need to be a physical
endpoint (as we’ll never load it).

Once the application is created, take a note of its Application Id, as we’ll need it later.

Authenticating on the client

// Call Login() based on your business logic (e.g. when a user presses a button)
conststringApplicationId="application-id-from-portal";conststringCommonAuthority="https://login.windows.net/common";conststringRedirectUri="redirect-uri-from-portal";publicasyncTask<User>Login(){varauthContext=newAuthenticationContext(CommonAuthority);varresponse=awaitauthContext.AcquireTokenAsync("https://graph.windows.net",ApplicationId,RedirectUri,newPlatformParameters(this));// We'll use response.AccessToken later
returnnull;}

The last argument of authContext.AcquireTokenAsync is a platform-specific implementation of IPlatformParameters,
so if you’re using a shared project to perform the authentication, you could either obtain it via dependency injection,
or add an #if PLATFORM directive. Once Login is called, the user will be presented with a webview where they can
enter their credentials:

After successful authentication, the response object will contain some basic user information as well as
an access token, that we’ll use to authenticate against the Realm Object Server.

Integrating with Realm

To authenticate against Realm Object Server, we’ll first need to enable the Azure Active Directory provider. Open up
configuration.yml, uncomment the azuread section and fill in the Directory Id, that can be found in the Properties
section:

# This enables authentication via an Azure Active Directory access token for a specific app.azuread:# The Directory Id as retrieved from the Active Directory properties in the Azure portal.tenant_id:'active-directory-id'

Now head back to the client application’s Login method to wrap it up:

conststringROSUrl="http://127.0.0.1";// Or the address where ROS is hosted
publicasyncTask<User>Login(){// same as above
// var response = (...);
varcredentials=Credentials.AzureAD(response.AccessToken);varuser=awaitUser.LoginAsync(credentials,ROSUrl);returnuser;}

What’s next at Realm

We’re excited to expand our support for the Microsoft ecosystem and our announcement today is one small step on that journey. This year, we’ve announced Realm Xamarin 1.0, Windows Desktop support, and easy ways to get your Realm Object Server (part of the Realm Mobile Platform) up and running on Azure. Stay tuned for more coming in 2017!

We’re releasing version 3.0 of Realm Java today. In this release we have enabled sorting across relationships and we’re giving our live collections RealmResults and RealmList a whole lot more life by adding fine-grained collection notifications, so that your app can respond to elements being added, deleted and modified.

Fine-grained Collection Notifications

Up until now, Realm has provided a single shared RealmChangeListener interface that could be registered on our Realm, RealmObject and RealmResults classes. However that interface came with a limitation. It could not provide information about what had changed, only that something had changed. In many cases that was good enough, but in some cases it was not. The most common example being if you wanted to animate changes in a RecyclerView. Due to Realm’s live-updating objects, the solution up until now have been to use a combination of realm.copyFromRealm() and the DiffUtil class from the Android Support Library. This was hardly ideal.

Today, we are shipping fine-grained collection notifications. It is a new interface that can be registered on RealmResults and will provide information about exactly which objects were added, deleted or changed. This will enable you to just refresh those elements that actually did change, making for a much nicer and responsive UI.

We’ve also updated our Android Adapters library, so the RealmRecyclerViewAdapter will now automatically use the fine-grained notifications for smoother animations. Here’s what it looks like in practice, compared to using RecyclerView without collection notifications:

privatefinalOrderedRealmCollectionChangeListener<RealmResults<Person>>changeListener=newOrderedRealmCollectionChangeListener(){@OverridepublicvoidonChange(RealmResults<Person>collection,OrderedCollectionChangeSetchangeSet){// `null` means the async query returns the first time.if(changeSet==null){notifyDataSetChanged();return;}// For deletions, the adapter has to be notified in reverse order.OrderedCollectionChangeSet.Range[]deletions=changeSet.getDeletionRanges();for(inti=deletions.length-1;i>=0;i--){OrderedCollectionChangeSet.Rangerange=deletions[i];notifyItemRangeRemoved(range.startIndex,range.length);}OrderedCollectionChangeSet.Range[]insertions=changeSet.getInsertionRanges();for(OrderedCollectionChangeSet.Rangerange:insertions){notifyItemRangeInserted(range.startIndex,range.length);}OrderedCollectionChangeSet.Range[]modifications=changeSet.getChangeRanges();for(OrderedCollectionChangeSet.Rangerange:modifications){notifyItemRangeChanged(range.startIndex,range.length);}}};

Fine-grained collection notifications work just like all other Realm listeners, so if a query was executed asynchronously (for example, by using findAllAsync()), then the fine-grained changeset will also be calculated on a background thread before delivering the result to the UI thread, without the memory overhead of using DiffUtil to calculate what’s changed.

Collection Snapshots

One of the key design principles for Realm is our concept of “live” objects and collections. It means that if you create a RealmResults from a query, it will stay up-to-date whenever the underlying data changes. This is very effective in any reactive architecture, where you can just register a RealmChangeListener and be notified when the query result is updated.

However in some cases, this “live” nature can lead to unexpected problems when looping over a live collection. Take this code for example:

Here, you make a query for all guests not invited, as you want to send an invite to them. If uninvitedGuests were a normal ArrayList, this would work as you expect and all guests would receive an invite.

However because RealmResults are live updated, and because you execute transactions inside the for-loop, Realm will automatically update the RealmResults after each iteration. This would in turn remove the guest from the uninvitedGuests list causing the entire array to shift, but because it is the for-loop keeping track of the current index, this would now be at the wrong position. The result was that only half the guests would receive an invite. Clearly not ideal.

Neither of these solutions were obvious though, so in Realm Java 0.89 we made the decision to defer all updates of RealmResults to the next looper event (by using Handler.postAtFrontOfQueue).

This had the advantage that the simple for-loop would work as expected, but it came with the price that the RealmResults could now get a little out of sync, e.g. if we deleted the guest objects instead of setting a boolean on them, they would still be present in the query result, but just as invalid objects.

realm.beginTransaction();
guests.get(0).deleteFromRealm(); // Delete the object from Realm
realm.commitTransaction();
guests.get(0).isValid() == false; // You could now get a reference to a deleted object.

This would rarely happen in practise though, so you could say we chose standard iterator behavior over staying true to core Realm architectural decisions.

In 3.0 we are revisiting this decision by making RealmResults fully live again, but to make it easier to work with live collections in simple for-loops, we’re adding a createSnapshot() method that can provide the current stable list. Simple for-loops should now use this snapshot if they intend to modify data in a loop (note that in most cases doing transactions in a loop is still an anti-pattern).

We are doing this for a number of reasons. One of them being internal refactorings needed to support fine-grained collection notifications. The other is that it means the semantics of Realm classes are all the same since both RealmResults and RealmList are fully live, and it is easier to both reason about them and document their usage. This had caused some confusion in the past, but we believe that fully supporting and documenting the live nature of Realm classes means we can offer users the most powerful APIs.

We are aware that this change might cause some headaches in existing code bases, but this change will only affect your work if you’re performing write transactions inside simple for-loops. In every other case, your code will continue to work as normal, and we hope that you agree it is better in the long term.

Sorting across relationships

Until now, it was only possible to sort RealmResults using “direct” properties. Starting with Realm Java 3.0, you can now sort query results by properties on the other side of an objects
many-to-one relationships

For example, to sort a collection of Person objects based on their dog’s age, you can now do the following: