Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Sync Data

Partition-Based Sync - Swift SDK

La sincronización basada en particiones es una moda antigua para utilizar Atlas Device Sync con Realm Swift SDK. Recomendamos usar Flexible Sync para nuevas aplicaciones. La información en esta página es para usuarios que aún están utilizando Partition-Based Sync.

Tip

El SDK de Realm Swift v10.40.0 y versiones posteriores permiten migrar de la sincronización basada en particiones a la sincronización flexible. Para obtener más información, consulte: Migrar de la sincronización basada en particiones a la sincronización flexible.

For more information about Partition-Based Sync and how to configure it in Atlas App Services, refer to Partition-Based Sync in the App Services documentation.

Cuando se selecciona Partition-Based Sync para la configuración de la aplicación de backend, la implementación del cliente debe incluir un valor de la partición. Este es el valor del campo clave de partición que se selecciona al configurar la Partition-Based Sync.

El valor de la partición determina a qué datos puede acceder la aplicación cliente.

You pass in the partition value when you open a synced realm.

Inicializa un realm sincronizado con una configuración de sincronización. Esto te permite especificar un valor de la partición cuyos datos deberían sincronizarse con el realm.

The first time you log in and open a synced realm, you'll log in the user, and pass the user's RLMSyncConfiguration object with the desired partitionValue to +[RLMRealm realmWithConfiguration:error:].

This opens a synced realm on the device. The realm attempts to sync with your App in the background to check for changes on the server, or upload changes that the user has made.

RLMApp *app = [RLMApp appWithId:YOUR_APP_ID];
// Log in...
RLMUser *user = [app currentUser];
NSString *partitionValue = @"some partition value";
RLMRealmConfiguration *configuration = [user configurationWithPartitionValue:partitionValue];
NSError *error = nil;
RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration
error:&error];
if (error != nil) {
NSLog(@"Failed to open realm: %@", [error localizedDescription]);
// handle error
} else {
NSLog(@"Opened realm: %@", realm);
// Use realm
}

Pasa el objeto de configuración de usuario con inicio de sesión con el valor de la partición deseado a inicializadores de realm.

Opcionalmente, puede especificar si un dominio debe descargar los cambios antes de abrirse. Si no especifica el comportamiento de descarga, se abre un dominio con datos del dispositivo e intenta sincronizar los cambios en segundo plano.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Store a configuration that consists of the current user,
// authenticated to this instance of your app. If there is no
// user, your code should log one in.
let user = app.currentUser
let partitionValue = "some partition value"
var configuration = user!.configuration(partitionValue: partitionValue)
// Open the database with the user's configuration.
let syncedRealm = try! Realm(configuration: configuration)
print("Successfully opened the synced realm: \(syncedRealm)")

New in version 10.23.0.

Si desea que un dominio no sincronizado comience a sincronizarse con otros dispositivos y el backend de App Services, puede usar el método writeCopy(configuration:) para crear una copia del dominio no sincronizado y usarla con una configuración de sincronización. El siguiente ejemplo crea una copia de un archivo de dominio no sincronizado, con todos sus datos existentes, que puede usar con una configuración de sincronización.

After you copy the realm for use with Sync, you can open the copy as a synced realm. Any changes you make to the synced realm will reflect in the synced realm file, and they will also propagate to other devices and the App Services backend.

Nota

Solo sincronización basada en particiones

This method only supports converting between a non-sync realm and Partition-Based Sync. If your app uses Flexible Sync, you must manually iterate through the objects in one realm and copy them into the other realm.

Tip

Si su aplicación accede a Realm en un async/await contexto, marque el código con @MainActor para evitar fallas relacionadas con subprocesos.

try await convertLocalRealmToSyncedRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func convertLocalRealmToSyncedRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in the user whose realm you want to open as a synced realm
let syncUser = try await app.login(credentials: Credentials.anonymous)
// Create a configuration to open the sync user's realm
var syncConfig = syncUser.configuration(partitionValue: "Your Partition Value")
syncConfig.objectTypes = [QsTask.self]
// Prepare the configuration for the user whose local realm you
// want to convert to a synced realm
var localConfig = Realm.Configuration()
localConfig.objectTypes = [QsTask.self]
// For this example, add some data to the local realm
// before copying it. No need to do this if you're
// copying a realm that already contains data.
let localRealm = addExampleData(config: localConfig)
// Create a copy of the local realm that uses the
// sync configuration. All the data that is in the
// local realm is available in the synced realm.
try! localRealm.writeCopy(configuration: syncConfig)
// Open the synced realm we just created from the local realm
let syncedRealm = try await Realm(configuration: syncConfig)
// Access the Task objects in the synced realm to see
// that we have all the data we expect
let syncedTasks = syncedRealm.objects(QsTask.self)
var frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 3)
print("Synced realm opens and contains this many tasks: \(frodoSyncedTasks.count)")
// Add a new task to the synced realm, and see it in the task count
let task4 = QsTask(value: ["name": "Send gift basket to Tom Bombadil", "owner": "Frodo"])
try! syncedRealm.write {
syncedRealm.add(task4)
}
frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 4)
print("After adding a task, the synced realm contains this many tasks: \(frodoSyncedTasks.count)")
// Open the local realm, and confirm that it still only contains 3 tasks
let openedLocalRealm = try await Realm(configuration: localConfig)
let localTasks = openedLocalRealm.objects(QsTask.self)
let frodoLocalTasks = localTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoLocalTasks.count, 3)
print("Local realm opens and contains this many tasks: \(frodoLocalTasks.count)")
XCTAssertNotEqual(frodoLocalTasks.count, frodoSyncedTasks.count)
/// Populate the local realm with some data that we'll use in the synced realm.
func addExampleData(config: Realm.Configuration) -> Realm {
// Prepare the configuration for the user whose local realm you
// want to convert to a synced realm
let localConfig = config
// Open the local realm, and populate it with some data before returning it
let localRealm = try! Realm(configuration: localConfig)
let task1 = QsTask(value: ["name": "Keep it secret", "owner": "Frodo"])
let task2 = QsTask(value: ["name": "Keep it safe", "owner": "Frodo"])
let task3 = QsTask(value: ["name": "Journey to Bree", "owner": "Frodo"])
try! localRealm.write {
localRealm.add([task1, task2, task3])
}
return localRealm
}
}

New in version 10.23.0.

Tip

Puedes pausar temporalmente una sesión de sincronización si no deseas cambiar permanentemente un realm sincronizado a uno no sincronizado. Consulta: Suspender o reanudar una sesión de sincronización.

Si deseas dejar de sincronizar permanentemente un realm con tu backend de aplicación Services, puedes utilizar el método writeCopy(configuration: ) para hacer una copia de un realm sincronizado para usarlo con una configuración sin sincronización. El siguiente ejemplo crea una copia del archivo Realm, con todos sus datos existentes, en una URL de archivo que especifiques.

Este proceso remueve el realm_id en el realm local. Debes incrementar la versión del esquema como si hubieras borrado una propiedad.

After you copy the realm for use without Sync, you can open the copy as a non-synced realm. Any changes you make to the non-synced realm reflect only in the local realm file. No changes propagate to other devices or the App Services backend.

Nota

Solo sincronización basada en particiones

This method only supports converting between a non-sync realm and Partition-Based Sync. If your app uses Flexible Sync, you must manually iterate through the objects in one realm and copy them into the other realm.

Tip

If your app accesses Realm in an async/await context, mark the code with @MainActor to avoid threading-related crashes.

try await convertSyncedRealmToLocalRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func convertSyncedRealmToLocalRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in the user whose realm you want to open as a local realm
let syncUser = try await app.login(credentials: Credentials.anonymous)
// Create a configuration to open the seed user's realm
var syncConfig = syncUser.configuration(partitionValue: "Some Partition Value")
syncConfig.objectTypes = [QsTask.self]
// Open the realm with the Sync user's config, downloading
// any remote changes before opening.
let syncedRealm = try await Realm(configuration: syncConfig, downloadBeforeOpen: .always)
print("Successfully opened realm: \(syncedRealm)")
// Verify the data we expect in the realm
// The synced realm we are copying contains 3 tasks whose owner is "Frodo"
let syncedTasks = syncedRealm.objects(QsTask.self)
var frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 3)
print("Synced realm opens and contains this many tasks: \(frodoSyncedTasks.count)")
// Construct an output file path for the local Realm
guard let outputDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
// Append a file name to complete the path
let localRealmFilePath = outputDir.appendingPathComponent("local.realm")
// Construct a local realm configuration
var localConfig = Realm.Configuration()
localConfig.objectTypes = [QsTask.self]
localConfig.fileURL = localRealmFilePath
// `realm_id` will be removed in the local realm, so we need to bump
// the schema version.
localConfig.schemaVersion = 1
// Check to see if there is already a realm at the local realm file path. If there
// is already a realm there, delete it.
if Realm.fileExists(for: localConfig) {
try Realm.deleteFiles(for: localConfig)
print("Successfully deleted existing realm at path: \(localRealmFilePath)")
} else {
print("No file currently exists at path")
}
// Make a copy of the synced realm that uses a local configuration
try syncedRealm.writeCopy(configuration: localConfig)
// Try opening the realm as a local realm
let localRealm = try await Realm(configuration: localConfig)
// Verify that the copied realm contains the data we expect
let localTasks = localRealm.objects(QsTask.self)
var frodoLocalTasks = localTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoLocalTasks.count, 3)
print("Local realm opens and contains this many tasks: \(frodoLocalTasks.count)")
let task = QsTask(value: ["name": "Send gift basket to Tom Bombadil", "owner": "Frodo"])
try! localRealm.write {
localRealm.add(task)
}
frodoLocalTasks = localTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoLocalTasks.count, 4)
print("After adding a task, the local realm contains this many tasks: \(frodoLocalTasks.count)")
frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 3)
print("After writing to local realm, synced realm contains this many tasks: \(frodoSyncedTasks.count)")
XCTAssertNotEqual(frodoLocalTasks.count, frodoSyncedTasks.count)
}

Puedes migrar tu App Services Device Sync Mode de Partition-Based Sync a Flexible Sync. La migración es un proceso automático que no requiere ningún cambio en el código de tu aplicación. La migración automática requiere la versión 10.40.0 o superior del SDK Realm Swift.

Migrating enables you to keep your existing App Services users and authentication configuration. Flexible Sync provides more versatile permissions configuration options and more granular data synchronization.

For more information about how to migrate your App Services App from Partition-Based Sync to Flexible Sync, refer to Migrate Device Sync Modes.

The automatic migration from Partition-Based Sync to Flexible Sync does not require any changes to your client code. However, to support this functionality, Realm automatically handles the differences between the two Sync Modes by:

  • Automatically creating Flexible Sync subscriptions for each object type where partitionKey == partitionValue.

  • Inyectar un campo partitionKey en cada objeto si aún no existe uno. Esto es necesario para la suscripción automática de Flexible Sync.

Si necesitas realizar actualizaciones en el código cliente después de la migración, considera actualizar tu base de código cliente para remover funcionalidades ocultas de migración. Tal vez quieras actualizar tu base de código de cliente cuando:

  • Agregue un nuevo modelo o cambie un modelo en su base de código de cliente.

  • You add or change functionality that involves reading or writing Realm objects

  • Quieres implementar un control más específico sobre los datos que sincronizas

Make these changes to convert your Partition-Based Sync client code to use Flexible Sync:

  • Switch to a flexibleSyncConfiguration() where you open a synced realm.

  • Agrega propiedades relevantes a tus modelos de objetos para usarlas en tus suscripciones de Flexible Sync. Por ejemplo, podrías agregar una propiedad ownerId para permitir que un usuario sincronice solo sus propios datos.

  • Remove automatic Flexible Sync subscriptions and manually create the relevant subscriptions.

For examples of Flexible Sync permissions strategies, including examples of how to model data for these strategies, refer to Device Sync Permissions Guide.

When you migrate from Partition-Based Sync to Flexible Sync, Realm automatically creates hidden Flexible Sync subscriptions for your app. The next time you add or change subscriptions, we recommend that you:

  1. Remove the automatically-generated subscriptions.

  2. Manually add the relevant subscriptions in your client codebase.

Esto le permite ver toda su lógica de suscripción junta en su base de código para futuras iteraciones y depuraciones.

For more information about the automatically-generated Flexible Sync subscriptions, refer to Migrate Client App to Flexible Sync.

Volver

Stream Data to Atlas

En esta página