La sincronización basada en particiones es un modo antiguo para usar Atlas Device Sync con el SDK de Realm Swift. Recomendamos usar la sincronización flexible para las nuevas aplicaciones. La información de esta página está dirigida a los usuarios que aún usan la sincronización basada en particiones.
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.
Para obtener más información sobre la sincronización basada en particiones y cómo configurarla en Atlas App Services, consulte Sincronización basada en particiones en la documentación de App Services.
Abrir un reino de sincronización basado en particiones
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.
Pasa el valor de la partición cuando abres un reino sincronizado.
Inicialice un dominio sincronizado con una configuración de sincronización. Esto le permite especificar un valor de partición cuyos datos deben sincronizarse con el dominio.
La primera vez que inicie sesión y abra un reino sincronizado, iniciará sesión como usuario y pasará el objeto RLMSyncConfiguration del usuario con el valor de partición deseado a +[RLMRealm realmWithConfiguration:error:].
Esto abre un dominio sincronizado en el dispositivo. Este dominio intenta sincronizarse con la aplicación en segundo plano para comprobar si hay cambios en el servidor o cargar los cambios realizados por el usuario.
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)")
Abrir un reino no sincronizado como un reino sincronizado
Nuevo en la versión 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.
Después de copiar el dominio para usarlo con Sync, puedes abrir la copia como un dominio sincronizado. Cualquier cambio que realices en el dominio sincronizado se reflejará en el archivo correspondiente y se propagará a otros dispositivos y al backend de App Services.
Nota
Solo sincronización basada en particiones
Este método solo admite la conversión entre un dominio sin sincronización y la sincronización basada en particiones. Si tu aplicación usa la sincronización flexible, debes iterar manualmente los objetos de un dominio y copiarlos al otro.
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. 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 } }
Abrir un reino sincronizado como un reino no sincronizado
Nuevo en la versión 10.23.0.
Tip
Puedes pausar temporalmente una sesión de sincronización si no quieres cambiar permanentemente un reino sincronizado a uno no sincronizado. Consulta: Suspender o reanudar una sesión de sincronización.
Si desea detener permanentemente la sincronización de un dominio con el backend de App Services, puede usar el método writeCopy(configuration:) para crear una copia del dominio sincronizado y usarla con una configuración no sincronizada. El siguiente ejemplo crea una copia del archivo del dominio, con todos sus datos, en la URL que especifique.
Este proceso remueve el realm_id en el realm local. Debes incrementar la versión del esquema como si hubieras borrado una propiedad.
Después de copiar el dominio para usarlo sin sincronización, puedes abrir la copia como un dominio no sincronizado. Cualquier cambio que realices en el dominio no sincronizado se reflejará solo en el archivo local del dominio. Los cambios no se propagan a otros dispositivos ni al backend de App Services.
Nota
Solo sincronización basada en particiones
Este método solo admite la conversión entre un dominio sin sincronización y la sincronización basada en particiones. Si tu aplicación usa la sincronización flexible, debes iterar manualmente los objetos de un dominio y copiarlos al otro.
Tip
Si su aplicación accede a Realm en un contexto async/await, marque el código con @MainActor para evitar fallas relacionadas con subprocesos.
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. 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) }
Migrar de la sincronización basada en particiones a la sincronización flexible
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.
La migración le permite conservar sus usuarios y configuración de autenticación de App Services. Flexible Sync ofrece opciones de configuración de permisos más versátiles y una sincronización de datos más granular.
Para obtener más información sobre cómo migrar su aplicación de App Services de sincronización basada en particiones a sincronización flexible, consulte Migrar modos de sincronización de dispositivos.
Actualización del código del cliente después de la migración
La migración automática de la sincronización basada en particiones a la sincronización flexible no requiere cambios en el código de cliente. Sin embargo, para facilitar esta funcionalidad, Realm gestiona automáticamente las diferencias entre los dos modos de sincronización mediante:
Creación automática de suscripciones de sincronización flexible para cada tipo de objeto donde
partitionKey == partitionValue.Inyectar un campo
partitionKeyen cada objeto si no existe. Esto es necesario para la suscripción automática a Sincronización Flexible.
Si necesita actualizar el código de su cliente después de la migración, considere actualizar su base de código para eliminar las funciones de migración ocultas. Le recomendamos actualizar su base de código cuando:
Agregue un nuevo modelo o cambie un modelo en su base de código de cliente.
Agrega o cambia funcionalidad que implica leer o escribir objetos de Realm
Desea implementar un control más preciso sobre los datos que sincroniza
Realice estos cambios para convertir el código de cliente de sincronización basada en particiones para utilizar la sincronización flexible:
Cambia a
flexibleSyncConfiguration()donde abres un reino sincronizado.Agregue propiedades relevantes a sus modelos de objetos para usarlas en sus suscripciones de Sincronización Flexible. Por ejemplo, podría agregar una propiedad
ownerIdpara permitir que un usuario sincronice solo sus propios datos.Elimine las suscripciones automáticas de sincronización flexible y cree manualmente las suscripciones relevantes.
Para obtener ejemplos de estrategias de permisos de sincronización flexible, incluidos ejemplos de cómo modelar datos para estas estrategias, consulte la Guía de permisos de sincronización de dispositivos.
Eliminar y crear suscripciones manualmente
Al migrar de la sincronización basada en particiones a la sincronización flexible, Realm crea automáticamente suscripciones ocultas de sincronización flexible para su aplicación. La próxima vez que agregue o modifique suscripciones, le recomendamos lo siguiente:
Esto le permite ver toda su lógica de suscripción junta en su base de código para futuras iteraciones y depuraciones.
Para obtener más información sobre las suscripciones de Flexible Sync generadas automáticamente, consulte Migrar la aplicación cliente a Flexible Sync.