Navigation

Sync Data

Info With Circle IconCreated with Sketch.Note

Realm Sync is currently in Beta.

Before you can access a synced realm from the client, you must:

To open a synced realm for a given partition value, initialize a Realm with a configuration object generated by passing the partition value to the authenticated user's configuration method:

let realm = try! Realm(configuration: configuration)
print("Opened realm: \(realm)")

If it is the first time opening that particular realm, especially if it is a read-only realm, use the Realm.asyncOpen() method instead:

Info With Circle IconCreated with Sketch.Note
Why Use asyncOpen?

The Realm() initializer is convenient, but upon first open of a given realm, it writes the schema to disk. The Realm server interprets this initial local schema as a write. If the realm is read-only, then the operation fails, causing the client to error out. Therefore, it is always recommended to use the Realm.asyncOpen() method the first time you open any given read-only realm.

let app = App(id: YOUR_REALM_APP_ID)
// Log in...
let user = app.currentUser
let partitionValue = "some partition value"
var configuration = user!.configuration(partitionValue: partitionValue)
// The following is only required if you want to specify exactly which
// types to include in the realm. By default, Realm automatically finds
// all subclasses of Object and EmbeddedObject to add to the realm.
configuration.objectTypes = [Task.self]
Realm.asyncOpen(configuration: configuration) { result in
switch result {
case .failure(let error):
print("Failed to open realm: \(error.localizedDescription)")
// handle error
case .success(let realm):
print("Successfully opened realm: \(realm)")
// Use realm
}
}

The partition value specifies which subset of your data to sync. This is typically a user ID, project ID, store ID, or some other category identifier in your app that has particular relevance to the current user.

Bulb IconTip

The syntax to read, write, and watch for changes on a synced realm is identical to the syntax for non-synced realms. While you work with local data, a background thread efficiently integrates, uploads, and downloads changesets.

Important With Circle IconCreated with Sketch.Important
When Using Sync, Avoid Writes on the Main Thread

The fact that Realm performs sync integrations on a background thread means that if you write to your realm on the main thread, there's a small chance your UI could appear to hang as it waits for the background sync thread to finish a write transaction. Therefore, it's a best practice never to write on the main thread when using Realm Sync.

The following code reads a collection of Task objects, watches that collection for changes, then writes a new Task to the realm:

// Read all tasks in the realm. No special syntax required for synced realms.
let tasks = realm.objects(Task.self)
// Watch for changes. No special syntax required for synced realms.
// Retain notificationToken as long as you want to observe.
let notificationToken = tasks.observe { (changes) in
print("Changed: \(changes)")
}
// Write to the realm. No special syntax required for synced realms.
try! realm.write {
realm.add(Task(partition: partitionValue, name: "My task"))
}
// Later, when done observing
notificationToken.invalidate()
Bulb IconTip
See Also:

If you want your app to update data in the background (while the app is minimized), iOS requires you to implement Background App Refresh. Enabling Background App Refresh minimizes the time it takes for the user to see the most recent data; without Background App Refresh, realm updates the data when the user launches the app, potentially resulting in a noticeable lag.

  • Open a synced realm with the configuration object generated when you pass a partition value to the user object's configuration method.
  • Compared to using a non-synced realm, there is no special syntax for reading from, writing to, or watching objects on a synced realm.
  • You should avoid writing to a synced realm on the main thread.
Give Feedback