Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Configure and Open a Database - SwiftUI

On this page

  • Open a Database with a Configuration
  • Open a Synced Database
  • Download Changes Before Opening a Synced Database
  • Open a Synced Database Offline

The Swift SDK provides property wrappers to open a database in a SwiftUI-friendly way.

You can:

  • Implicitly open a database with a defaultConfiguration or specify a different configuration. This works for both non-synced and synced databases.

  • Always download changes before opening a synced database, which times out when the user is offline.

  • Open a synced database even when a user is offline. The database may lack the most recent data.

When you use @ObservedRealmObject or @ObservedResults, these property wrappers implicitly open a database and retrieve the specified objects or results.

// Implicitly use the default realm's objects(Dog.self)
@ObservedResults(Dog.self) var dogs

Note

The @ObservedResults property wrapper is intended for use in a SwiftUI View. If you want to observe results in a view model, register a change listener.

When you do not specify a configuration, these property wrappers use the defaultConfiguration. You can set the defaultConfiguration globally, and property wrappers across the app can use that configuration when they implicitly open a database.

You can provide alternative configurations that the property wrappers use to implicitly open the database. You might want to do this when using multiple configurations in your app, as in cases where you have both a SyncConfiguration and a local Configuration. To do this, create explicit configurations. Then, use environment injection to pass the respective configurations to the views that need them. Passing a configuration to a view where property wrappers open a database uses the passed configuration instead of the defaultConfiguration.

New in version 10.12.0.

These SwiftUI property wrappers open synced databases and populate views. The main difference between these property wrappers is whether the user must be online:

  • To download updates from your Atlas App Services app before opening a database, use the @AsyncOpen property wrapper. This requires the user to have a network connection.

  • To open a synced database regardless of whether the user has a network connection, use the @AutoOpen property wrapper. This property wrapper enables developers to design offline-first capabilities into their apps.

Use the @AsyncOpen property wrapper for apps that require up-to-date information from the server, such as game apps with live leaderboards that the user can play on multiple devices. This ensures the user is never using the app with stale data.

You can add subscription queries in .onAppear after opening the database.

@AsyncOpen(appId: flexibleSyncAppId, timeout: 4000) var asyncOpen

You can create a flexibleSyncConfiguration() with the initialSubscriptions parameter. You can use this parameter to subscribe to Sync queries in the configuration. If this runs more than once - for example, if it's in a view that reloads regularly - check whether the subscription exists already before adding it. Adding the same subscription again throws an error.

// Create a `flexibleSyncConfiguration` with `initialSubscriptions`.
// We'll inject this configuration as an environment value to use when opening the realm
// in the next view, and the realm will open with these initial subscriptions.
let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
let peopleSubscriptionExists = subs.first(named: "people")
let dogSubscriptionExists = subs.first(named: "dogs")
// Check whether the subscription already exists. Adding it more
// than once causes an error.
if (peopleSubscriptionExists != nil) && (dogSubscriptionExists != nil) {
// Existing subscriptions found - do nothing
return
} else {
// Add queries for any objects you want to use in the app
// Linked objects do not automatically get queried, so you
// must explicitly query for all linked objects you want to include.
subs.append(QuerySubscription<Person>(name: "people"))
subs.append(QuerySubscription<Dog>(name: "dogs"))
}
})

Then, pass the configuration to the view that contains the property wrappers as an environment object.

OpenFlexibleSyncRealmView()
.environment(\.realmConfiguration, config)

For a complete example, see the SwiftUI Quick Start.

This SwiftUI property wrapper initiates Realm.asyncOpen() for the current user. The property wrapper publishes states, represented by the AsyncOpenState enum, which you can use to update the view.

Example

This example illustrates one way you might use @AsyncOpen to open a database in a view. First, check for a user, or log them in. Then, attempt to open the database, switching on the AsyncOpenState to display an appropriate view. When the database opens successfully, inject it as an environment value to populate the view.

/// This view opens a synced realm.
struct OpenFlexibleSyncRealmView: View {
// We've injected a `flexibleSyncConfiguration` as an environment value,
// so `@AsyncOpen` here opens a realm using that configuration.
@AsyncOpen(appId: flexibleSyncAppId, timeout: 4000) var asyncOpen
var body: some View {
switch asyncOpen {
// Starting the Realm.asyncOpen process.
// Show a progress view.
case .connecting:
ProgressView()
// Waiting for a user to be logged in before executing
// Realm.asyncOpen.
case .waitingForUser:
ProgressView("Waiting for user to log in...")
// The realm has been opened and is ready for use.
// Show the content view.
case .open(let realm):
// Do something with the realm
UseRealmView(realm: realm)
// The realm is currently being downloaded from the server.
// Show a progress view.
case .progress(let progress):
ProgressView(progress)
// Opening the Realm failed.
// Show an error view.
case .error(let error):
ErrorView(error: error)
}
}
}

Like @AsyncOpen, @AutoOpen attempts to download updates before opening the database. However, if a network connection is not available, this method instead opens a database with data on the device.

Use this property wrapper for apps where it's not a problem for the user to work with potentially stale data, such as note-taking apps where users should be able to work with data on the device

@AutoOpen(appId: "app_id") var autoOpen

This SwiftUI property wrapper attempts to download updates before opening a database for the current user. If there is no internet connection, this property wrapper instead returns the most up-to-date version of the local database file for the given appId and Sync configuration.

The property wrapper publishes states, represented by the AsyncOpenState enum, which you can use to update the view. For a full example, see the @AsyncOpen code examples above.

← Change an Object Model