Realm Offers a Multi-Platform Database

Realm Database series header

This is the third post in a multi-part series on the Realm Database; it highlights some of the multi-platform aspects of the the database and the high reusability of the code across devices. If you missed the first post on our custom engine or the second post on the benefits of some of the Realm API types, we recommend taking few minutes to read through. Also, make sure to check out the fourth post highlighting how a flexible, solid SDK like Realm’s empowers good development practices., the fifth post on Realm SDK features that allow developers to provide partial UI updates based on fine-grained notifications, and the final and sixth post, which shows how the features in the previous parts come together to make a database for modern mobile apps.


The Realm Database was designed from the ground up to run on mobile devices. At the time both iOS and Android used to lack a present day, modern database designed for the specific needs of mobile developers: working easily with objects instead of writing SQL queries, a very high-performant engine that allows for quick chunks of work even on the main thread, an expressive native language API, and more.

As mentioned in the previous post in this series, the Realm Database is written in super fast C++ (the database core is open source, and you’re welcome to peek in).

Realm SDKs: Java, Objective-C, React Native, Swift, Xamarin

Since C++ code runs almost anywhere, running on both Apple devices and Android is a piece of cake for the Realm Database. In fact, both platforms offers almost the same features and differ only in the syntax of the high-level API:

Get more development news like this

  • Swift developers use a more swifty API,
  • Objective-C programmers enjoy a native Cocoa style API,
  • and Android developers use an API, which is more Java like.

In fact, to make sure as many as possible mobile developers can use its database, Realm offers high-level APIs for some multi-platform solutions as well:

  • C# developers can create both iOS and Android apps using Xamarin Studio,
  • and JavaScript developers can use it with ReactNative.

Sharing Your Data Layer Across the Apple Platforms

Sometimes it’s easy to forget that each Apple device runs a different operating system. Kudos to Apple for making it so easy to write cross-platform code!

You are, however, using a different SDK when creating a full-blown Mac, or an Apple Watch application. You use the same programming language - Swift (or Objective-C), but it is a different SDK and a different OS.

Thanks to the fact that Apple has made it so easy to create multi-platform projects and to reuse code you have laying around, you can share a lot between projects no matter which platform you’re using. With Realm, you can share your database layer as well!

In this post, we are going to have a look at a project that shares its data layer between iOS, macOS, tvOS, and watchOS.

Realm poweres watchOS, iOS, macOS, and tvOS apps

You can clone the project from GitHub and run it locally if you want to play around with it.

We’re going to be looking into a “Top GitHub Repos” app - it loads the Top 100 popular Swift repos from GitHub and allows the user to search and favorite them. Not a very complex example, yet it clearly demonstrates the benefits of re-using the whole data layer between platforms.

The Xcode project has specific code for each supported platform. The code that only depends on Apple’s Foundation, like the networking layer, is shared between all platforms.

Oh yes - also Realm objects and the whole data layer is shared between all platforms because these depend only on Foundation and RealmSwift:

Demo project shared files

When you run the Mac version of the project you will see a typical Mac app pop up on screen:

Mac app powered by Realm

When you run the Watch target you will see the Watch Simulator display an app with the typical UI for that OS:

Apple Watch app powered by Realm

Note: It might take quite a while until the watch simulator fetches the repos from GitHub though. In a production app you’d like to fetch them from the companion iOS app instead (we wanted to focus on code sharing in this example).

Let’s have a look at some of the code (it’s pretty easy to read through even if your favorite language is different).

One of the Realm objects all those apps share is Favorite - it allows for a Repository to be marked as a favorite and assign it a favorite symbol:

import Foundation
import RealmSwift

class Favorite: Object {
    
  //persisted property
  dynamic var symbol = "💖"

  //dynamic property
  var symbolIndex: Int? {
    return Favorite.symbols.index(of: symbol)
  }

  //static properties
  static let symbols = ["💖", "🚀", "🤕"]
  static let noSymbolIndex = -1
}

The class features both persisted and dynamic properties but all said and done the only two frameworks it depends on are Foundation and RealmSwift. This makes the class shareable across all platforms that those two support. If you check the file membership in Xcode you’ll see the file is re-used as-is in all four targets:

Demo project shared files

The benefit of being able to share and re-use code is that you get to write it only once, test it once, and your data entities can never get out of sync between the different versions of the app.

If you read further in that same file, you will see that Favorite features even some simple helper methods:

// MARK: - Favorite model methods

extension Favorite {
  func set(symbol newSymbol: String?) throws {
    guard let realm = realm, 
      let symbol = newSymbol else { return }

    try realm.write {
      self.symbol = symbol
     }
  }
}

For a more complete business logic implementation, you’d probably like to create a separate structure of classes. But some basic methods like the one above could also go directly in the Favorite class and be re-used along with the entity definition itself.

I hope this overview really puts the phrase “write once, use anywhere” in perspective! In the next post, we’ll discuss in a bit more detail how the re-usability of Realm objects and the excellent level of isolation allows for a better app architecture.

Sharing Data Entities Even Further

So far you’ve seen how to re-use code across four different operating systems, but they were all within the Apple eco-system.

You can share code in both Swift and Objective-C across those four Apple platforms, but you would most certainly want to expand to Android in order to reach another multitude of mobile users.

Let’s translate the Favorite class in Java for the Android version of the same app:

public class Favorite extends RealmObject {
   @Required
   private String symbol = "💖";
   private static String[] symbols = {"💖", "🚀", "🤕"};
   public static final int NO_SYMBOL_INDEX = -1;

   public String getSymbol() {
     return symbol;
   }

   public void setSymbol(String symbol) {
     if (symbol == null) return;
     this.symbol = symbol;
   }

   public int getSymbolIndex() {
     for (int i = 0; i< symbols.length; i++) {
       if (symbols[i].equals(symbol)) {
         return i;
       }
     }
     return NO_SYMBOL_INDEX;
   }
}

It’s visible even to the naked eye how similar those classes are, yet not completely identical. They do however bind to the same underlying C++ structure and ultimately to the same data stored on disc.

There are few interesting aspects to that fact.

You, obviously, cannot re-use the code as-is between iOS and Android, since one is written in Swift or Objective-C and the other is in Java.

You can, however, easily keep them in line - you see that the basic data types are the same, and Realm’s API to create object relationships is identical.

Even further - you can choose to re-create the same simple helper methods you have included in your class across platforms. Then the two entities are identical across iOS and Android, and you can also synchronize the test suits covering Favorites and its behavior!

Keeping your entities identical across platforms does have a greater benefit than just coherence, re-usability, better testability, and the simple joy of using a fantastic API across platforms.

And now for the real kicker - once you install the free Realm Platform on your own server, you will provide out-of-the-box data synchronization between your tvOS, macOS, iOS and Android apps!

The data syncing will come at no cost since your entities already have the same structure and the Realm Object Server will know exactly how to keep them in sync.

We Hope You Like What You’re Seeing!

We’ve looked a bit into multi-platform solutions with Realm Database. But a solid, reusable data layer is just the foundation of a robust mobile app, and we’re going to explore this in more detail in the next posts in this series.

As always, if you have few extra minutes, you are welcome to check out the Realm Database:

In the next installment in this series, we’re going to look in more detail into this series’ companion project. We’re going to see how the Realm API empowers a clean and flexible app architecture.

See you next time! 👋

About the content

This content has been published here with the express permission of the author.


Marin Todorov

Marin Todorov is an independent iOS consultant and publisher. He’s co-author on the book “RxSwift: Reactive programming with Swift” the author of “iOS Animations by Tutorials”. He’s part of Realm and raywenderlich.com. Besides crafting code, Marin also enjoys blogging, writing books, teaching, and speaking. He sometimes open sources his code. He walked the way to Santiago.

4 design patterns for a RESTless mobile integration »

close