In this tutorial, I’ll continue from my previous tutorial on
Realm
Mobile Database for iOS
where we learned about Realm Mobile Database, an on-device database alternative to
Core Data. Realm has also developed an equally elegant and seamless server-side solution
that syncs our data between our device and the cloud in real time.
This is part of Realm’s flagship solution, Realm Mobile Platform.
In this post, we
will install a Realm Object Server
and improve on the RealmDo app that we started in the previous post.
-
iOS SDKRealm Mobile Database for iOS
What Is Realm Mobile Platform?
Announced in early 2017, Realm
Mobile Platform 1.0 represents the company’s efforts to extend its database onto the cloud and provide support
for more collaborative features such as live messaging, offline-first
experiences, and more impressively, cross-platform. Through the new Realm Object Server, Realm
Mobile Platform takes over and handles the complexities of marshaling and synchronizing data between the Realm
Database and server.
Realm Mobile Platform acts as a conduit between the
Realm Object Server and your Realm Mobile Database. When you persist data
locally on your device, it gets pushed in real-time, but with the ability to
queue and defer-synchronize when offline.
In addition to synchronizing data (or Realms) between
devices, Realm Object Server also provides authentication and access
control services (permission management), as well as serverless event processing through Realm Functions. Let’s learn
more about what Realm Mobile Platform
provides. Note that some of these features are available to enterprise customers
only.
Realm Functions
Realm
Functions
act as the app logic layer, powered
by JavaScript, allowing you to execute custom logic without a dedicated server and to respond to
changes on one or all Realms (databases).
Through the Realm Dashboard you can author, start,
stop and delete functions that respond to changes on one or more Realms, with serverless Event
Handling.
You create functions using JavaScript and Node.js, and the functions are called by the Realm Object Server’s global listening API.
Currently, the developer edition of Realm Mobile Platform is
limited to three active functions at any given time, although you are able
to have more functions which are inactive.
Realm Functions are outside the scope of this tutorial,
but certainly worth reading up on.
Realm Dashboard
The Realm
Dashboard
comes baked in with the Realm Object Server installation, as we will illustrate
shortly, providing a convenient tool for managing your Realms, managing users and functions, and getting a pulse on how your application server is
running.
The browser-based dashboard consists of the following
sections:
-
Dashboard provides a real-time pulse of data rates in and out, open connections and
open Realms. -
Realms
provides paths, permissions and owners of each of the Realms, and you can
traverse down each Realm to view the models and contents of individual Realms. -
Users
provides information and management services for all users, including granting
and removing administrative permissions. -
Functions
is where you create and manage your Realm Functions. -
Logs
is where you can view System logs for the Object Server.
The Dashboard is normally
accessible via the http://localhost:9080 path locally, or
wherever your hosted machine lies.
Realm Connection
This is an enterprise-only feature, though very useful for some businesses. Realm connection is a conduit that exposes corporate legacy systems to the platform through a modern API gateway, making it easier for developers to hook into previously obfuscated data sources.
The Enterprise Edition of the Realm Object Server offers a Node.js-based adapter API that allows you to access all low-level Object Server operations and data. This can be used to let a synced Realm interact with an existing legacy database such as PostgreSQL: the Realm will also be kept in sync with the external database in real time. Client applications can use the Realm Mobile Database API and get the benefits of working with real-time, native objects.
Service Tiers
The company currently offers three tiers of service. The Developer Edition is
the free-tier for small teams, where users would benefit from features like
real-time automatic data-sync using live objects. The Professional Edition adds advanced features such as event handling
and server-side access.
Catering to the demands of mid-sized teams, the Professional Edition is a good
middle ground without the overhead of the Enterprise Edition. Costs are adjusted to your scale, providing an easy migration path from the
free tier.
The Professional Edition starts at $1,500 per month, and the
Enterprise Edition is custom priced based on the use case.
Your First Realm Server App
Assumed Knowledge
This tutorial assumes you have a working knowledge of Swift,
but no Core Data or prior database knowledge is needed. Additionally, it is assumed you have gone
through the previous tutorial on Realm
Mobile Database for iOS
and have completed the tutorial exercises to create the RealmDo
app. We’re
going to continue from where we left off in that post, and add server-side
functionality to our app, RealmDo.
As well as Realm, we’ll be using the following parts of iOS:
- UIKit: to demonstrate our data visually
-
CocoaPods: a third-party dependency library
that will be used to install Realm Mobile Database
Objectives of This Tutorial
By the end of this tutorial, you will have continued to
build on your knowledge of Realm and enhance the simple to-do app written in
Swift, by persisting data remotely on the server through Realm Mobile
Platform. You’ll get to create a fully functioning Realm-powered to-do app with a server-side back-end, and along the
way you’ll learn the following concepts:
- setting up the Realm Object Server locally
- synchronizing the ‘live-object’ model to the
Realm Object Server - monitoring data through the dashboard
You can download the
complete source code from the tutorial GitHub repo.
Set Up the Realm Object Server
Before we hit Xcode once again to work our project, we will
need to set up and get our Realm Object Server running.
Download the macOS
bundle,
assuming you will be installing the Object Server locally on your Mac. If you
are going to be installing it on a Linux server, refer to the Realm
documentation.
Once you’ve completed the download, in terminal navigate to
your Downloads/realm-mobile-platform
folder and start the server by typing:
start-object-server.command
Your terminal should now indicate that your server is
starting, and your browser will automatically open to launch the
Realm Dashboard, at http://localhost:9080.
You will be asked to register as a new user and provide an email and
password the first time you run the server. Please go ahead and complete the
registration process and remember your credentials, as you will be using them
later on.
Keep this browser window open as we will return to it later
when we run our complete app, to observe how data is stored on the server.
Making Our Project Syncable
Now we are set to start coding, so go ahead and fire up the
Xcode project we were working on in the previous tutorial, as we are going to
continue to build from there, in the view
controller.
The first thing we will do is amend our remindersList
global variable to be mutable, so we will need to
change it from an RLMResults
object to a List
type. We will also be adding a new
object type, NotificationToken
, which
we will use to notify us of when there is a change in the realm data
object.
NotificationToken
isn’t a server-specific object, and we could have used it in our previous
tutorial, but it certainly comes in handy when we want to detect real-time changes
remotely or locally and react accordingly.
var notificationToken: Notification? var remindersList = List()
Within the viewDidLoad()
method, we will embed a SyncUser.logIn()
method, which is Realm’s authentication mechanism, accepting a username,
password, and server location. This is an interesting topic in its own right, beyond
the scope of this tutorial, but for now, we will just hard-code in the
credentials we set when we registered our Realm Object Server previously.
We also pass in the server location, along with the name of
the realm (database) we want to use, which is http://127.0.0.1:9080. In the realm configuration line, in addition
to the server location, you must also set the realm name, which is realmDoApp for the purposes of this
demonstration. Go ahead and replace your viewDidLoad()
with the following:
override func viewDidLoad() { super.viewDidLoad() tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") // You should make the username and password user-input supported SyncUser.logIn(with: .usernamePassword(username: "[email protected]", password: "test123", register: false), server: URL(string: "http://127.0.0.1:9080")!) { user, error in guard let user = user else { fatalError(String(describing: error)) } DispatchQueue.main.async(execute: { // Open Realm let configuration = Realm.Configuration( syncConfiguration: SyncConfiguration(user: user, realmURL: URL(string: "realm://127.0.0.1:9080/~/realmDoApp")!) ) self.realm = try! Realm(configuration: configuration) // Set realm notification block self.notificationToken = self.realm.addNotificationBlock{ _ in self.updateRemindersList() } self.updateRemindersList() }) } }
In a real-world application, we would get user credentials with a form. In the code above, though, we hard-code our credentials and set a user object once the login is successful. Otherwise, the
application will fail with a fatal error.
Finally, the code above uses a synchronous
block to associate the realm instance to the realm object server (instead of the on-device
database). This is the distinctive line that makes this app cloud-based.
At the end, I initialize the notificationToken
to call a method, updateRemindersList()
, every time there is a change in the realm data (locally or remotely).
func updateRemindersList(){ if self.remindersList.realm == nil{ self.remindersList = self.realm.objects(Reminder.self).reduce(List()) { (list, element) -> List in list.append(element) return list } } self.tableView.reloadData() }
The code block above also converts the self.realm.objects()
it receives from the server, so that we can associate the results with our newly
List
-typed RemindersList
set of objects.
Notice how it is ambiguous whether we are getting the data
from our realm database or remotely. This is what makes Realm great—you don’t
have to worry about synchronization locally or remotely!
And that is it—all the code that is needed to make the app
work with Realm Object Server. There is one final thing needed prior to
building and running the app. Open up the project’s info.plist as Source Code by right-clicking on the file. Add the following to allow non-TLS requests to work.
NSAppTransportSecurity NSAllowsArbitraryLoads
Now, go ahead and build and then run the application, and add a
few new reminders. We will switch over to the browser now, where we can see the running server and access its dashboard to observe data being populated into a new
realm.
Monitoring Data via Dashboard
Now we are going to monitor and oversee the data through the dashboard that we launched when we started the Realm Object
Server. Running the app and dashboard
side by side, you can see that when you add an item, it immediately shows up on
the dashboard. The same happens when you remove an item, demonstrating that it is
indeed real-time.
Monitoring Data via Realm Browser
You can also use Realm Browser to monitor your app data. In the previous tutorial, we used Realm Browser to view our on-device data. We can also use it to view Realm Object Server data.
Launch the app, select Open Sync URL, and type in the location of your remote object server realm (e.g. realm://127.0.0.1:9080/8e090f0fa57366808be106e004800a0f/realmDoApp)
along with your username and email. You should get the familiar view we saw in the last tutorial, only this time we are connecting to a real-time back end!
Go ahead and change your properties there, and you should
see that reflected in the Dashboard as well as in your app.
Conclusion & Next Steps
In this tutorial, you learned how to extend a Realm Mobile Database-powered application—which is very powerful already—with a back-end server solution. All with only a few lines of code.
In addition to downloading and installing Realm Object Server, we improved our simple reminders app with the following features:
- a simple authentication mechanism
- real-time back-end synchronization
Finally, we saw how to monitor live data through the dashboard, as well as through the familiar Realm Object Browser.
The premise of platforms like Realm Object Server is to have developers focus on their client-side code and not worry about the complexities of maintaining a back-end server
We’ve just scratched the surface in this post. There are lots of documentation and concepts with Realm Object Server, including working with functions to allow for serverless logic triggering.
Check back here for more posts on back-end services for mobile app development.
-
Android SDKServerless Apps With Firebase Cloud Functions
-
Android SDKCreate an Intelligent App With Google Cloud Speech and Natural Language APIs
-
Mobile DevelopmentBack-End as a Service for Mobile Apps