Docs Menu

Add Device Sync to an App - Swift SDK

On this page

  • Prerequisites
  • Add Device Sync to a Client Application
  • Connect to the App Services backend
  • Authenticate a user
  • Open a Synced Realm
  • Use the Realm
Tip
See also:

This page contains information about how to add Device Sync to an app. If you are looking for information about what Device Sync is and how it works, see: Application Services: Sync Data.

Before you can access a synced realm from the client, you must Enable sync in the App Services UI. During this process, you must define queryable fields that match fields in your schema. You also define read and write permissions for app users.

In this example, our model includes an ownerId field that maps to the user.id of the Flexible Sync user.

class Todo: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name: String = ""
@Persisted var ownerId: String
@Persisted var status: String = ""
convenience init(name: String, ownerId: String) {
self.init()
self.name = name
self.ownerId = ownerId
}
}
1

Pass the App ID for your App, which you can find in the Atlas App Services UI.

let app = App(id: FLEX_SYNC_APP_ID) // Replace FLEX_SYNC_APP_ID with your Atlas App ID
2

Authenticate a user in your client project. Here, we'll use anonymous authentication.

func login() async throws -> User {
// Authenticate with the instance of the app that points
// to your backend. Here, we're using anonymous login.
let user = try await app.login(credentials: Credentials.anonymous)
print("Successfully logged in user: \(user)")
return user
}
3

Open the realm as a synced realm. You can specify whether a synced realm should download data before it opens. Here, we use a Flexible Sync configuration and specify that the SDK should always download the most recent updates before opening the realm. We bootstrap the realm with an initial subscription. We also specify the object types that we want to include in this realm.

func openSyncedRealm(user: User) async {
do {
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(
QuerySubscription<Todo> {
$0.ownerId == user.id
})
})
// Pass object types to the Flexible Sync configuration
// as a temporary workaround for not being able to add a
// complete schema for a Flexible Sync app.
config.objectTypes = [Todo.self]
let realm = try await Realm(configuration: config, downloadBeforeOpen: .always)
useRealm(realm, user)
} catch {
print("Error opening realm: \(error.localizedDescription)")
}
}

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.

The following code creates a new Task object and writes it to the realm:

let todo = Todo(name: "Do laundry", ownerId: user.id)
try! realm.write {
realm.add(todo)
}
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 not to write on the main thread when using Device Sync.

←  Sync Data Between Devices - Swift SDKConfigure & Open a Synced Realm - Swift SDK →
Give Feedback
© 2022 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.