Docs Menu
Docs Home
/ /
Archivos del reino

Agrupar un archivo Realm - Swift SDK

Nota

Paquete de reinos sincronizados

La versión 10.23.0 del SDK de Swift introdujo la posibilidad de agrupar dominios sincronizados. Antes de la versión 10.23.0, solo se podían agrupar dominios locales.

Realm permite agrupar archivos de realm. Al agrupar un archivo de realm, se incluye una base de datos y todos sus datos en la descarga de la aplicación.

Esto permite a los usuarios iniciar aplicaciones por primera vez con un conjunto de datos iniciales. En el caso de los dominios sincronizados, la agrupación puede evitar una larga descarga inicial la primera vez que un usuario abre la aplicación. En su lugar, los usuarios solo necesitan descargar los cambios sincronizados realizados desde que se generó el archivo agrupado.

Importante

Agrupación de reinos sincronizados

Si su aplicación backend utiliza Sincronización flexible: los usuarios podrían experimentar un reinicio del cliente la primera vez que abren el archivo de dominio incluido. Esto puede ocurrir cuando el tiempo máximo sin conexión del cliente está habilitado (esta opción está habilitada por defecto). Si el archivo de dominio incluido se generó más de los días especificados en la configuración de tiempo máximo sin conexión del cliente antes de que el usuario sincronice por primera vez, el cliente se reiniciará.

Las aplicaciones que reinician el cliente descargan el estado completo del dominio desde el backend de la aplicación. Esto anula las ventajas de agrupar un archivo de dominio. Para evitar reinicios del cliente y conservar las ventajas de agrupar archivos de dominio:

  • Evite utilizar un tiempo máximo sin conexión del cliente en aplicaciones que agrupan un reino sincronizado.

  • Si su aplicación utiliza un tiempo máximo de desconexión del cliente, asegúrese de que la descarga de la aplicación siempre incluya un archivo de dominio sincronizado recientemente. Genere un nuevo archivo con cada versión de la aplicación y asegúrese de que ninguna versión permanezca actualizada durante más días que el tiempo máximo de desconexión del cliente.

Para crear y agrupar un archivo de reino con su aplicación:

  1. Crea un archivo de reino que contenga los datos que deseas agrupar.

  2. Agrupe el archivo de reino en su aplicación de producción.

  3. En su aplicación de producción, abra el dominio desde el archivo de recursos incluido. Para dominios sincronizados, debe proporcionar la clave de partición.

  1. Cree una aplicación de reino temporal que comparta el modelo de datos de su aplicación.

  2. Abra un dominio y agregue los datos que desea agrupar. Si usa un dominio sincronizado, espere a que se sincronice por completo.

  3. Utilice el método writeCopy(configuration:) para copiar el reino a un nuevo archivo:

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 createBundledRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func createBundledRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in the user whose realm you want to copy for bundling
let seedUser = try await app.login(credentials: Credentials.anonymous)
// Create a configuration to open the seed user's realm
var config = seedUser.configuration(partitionValue: "Partition You Want to Bundle")
config.objectTypes = [Todo.self]
// Open the realm with the seed user's config
let realm = try await Realm(configuration: config, downloadBeforeOpen: .always)
print("Successfully opened realm: \(realm)")
// Verify there is a todo object in the realm whose
// owner's name is "Daenerys". When we open the bundled
// realm later, we should see the same result.
let todos = realm.objects(Todo.self)
let daenerysTodos = todos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysTodos.count, 1)
// Specify an output directory for the bundled realm
// We're using FileManager here for tested code examples,
// but this could be a static directory on your computer.
guard let outputDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
// Append a file name to complete the path
let bundleRealmFilePath = outputDir.appendingPathComponent("seed.realm")
// Update the config file path to the path where you want to save the bundled realm
config.fileURL = bundleRealmFilePath
// Check to see if there is already a realm at the bundled realm file path. If there
// is already a realm there, delete it.
if Realm.fileExists(for: config) {
try Realm.deleteFiles(for: config)
print("Successfully deleted existing realm at path: \(bundleRealmFilePath)")
} else {
print("No file currently exists at path")
}
// Write a copy of the realm at the URL we specified
try realm.writeCopy(configuration: config)
// Verify that we successfully made a copy of the realm
XCTAssert(FileManager.default.fileExists(atPath: bundleRealmFilePath.path))
print("Successfully made a copy of the realm at path: \(bundleRealmFilePath)")
// Verify that opening the realm at the new file URL works.
// Don't download changes, because this can mask a copy
// that does not contain the expected data.
let copiedRealm = try await Realm(configuration: config, downloadBeforeOpen: .never)
print("Successfully opened realm: \(realm)")
// Verify that the copied realm contains the data we expect
let copiedTodos = copiedRealm.objects(Todo.self)
let daenerysCopiedTodos = copiedTodos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysCopiedTodos.count, 1)
print("Copied realm opens and contains this many tasks: \(daenerysCopiedTodos.count)")
}

writeCopy(configuration: ) compacta automáticamente su reino al tamaño más pequeño posible antes de copiar.

Nota

Diferencias entre los dominios sincronizados y los dominios solo locales

El ejemplo anterior usa SyncConfiguration para configurar un dominio sincronizado. Para crear una copia de un dominio local, configure su dominio con RealmConfiguration.

Ahora que tiene una copia del dominio que contiene los datos iniciales, incorpórela a su aplicación de producción. En general, esto implica:

  1. Crea un nuevo proyecto con los mismos modelos de datos que tu aplicación de producción. Abre un realm y añade los datos que quieres agrupar. Dado que los archivos realm son multiplataforma, puedes hacerlo en una aplicación macOS.

  2. Arrastre la copia compactada de su archivo de reino al Navegador de proyectos Xcode de su aplicación de producción.

  3. Vaya al objetivo de su aplicación Build Phases Pestaña en Xcode. Agregue el archivo realm a la fase de compilación Copy Bundle Resources.

  4. En este punto, tu aplicación puede acceder al archivo de dominio incluido. Encuentra su ruta con Bundle.main.path(forResource:ofType).

Puedes abrir el Realme directamente en la ruta del paquete si la propiedad readOnly está configurada en true en la Configuración de Realm. Si deseas modificar el Realm incluido en el paquete, primero copia el archivo incluido en la carpeta Documentos de tu aplicación configurando seedFilePath con la URL del Realm incluido en tu configuración.

Tip

Consulta la aplicación de ejemplo de migración para una aplicación funcional completa que usa un realm local integrado.

Ahora que tiene una copia del dominio incluida en su aplicación de producción, necesita agregar código para usarla. Use el método seedFilePath al configurar su dominio para abrirlo desde el archivo incluido:

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 openBundledSyncedRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func openBundledSyncedRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in an app user who will use the bundled realm
let user = try await app.login(credentials: Credentials.anonymous)
// Create a configuration for the app user's realm
// This should use the same partition value as the bundled realm
var newUserConfig = user.configuration(partitionValue: "Partition You Want to Bundle")
newUserConfig.objectTypes = [Todo.self]
// Find the path of the seed.realm file in your project
let realmURL = Bundle.main.url(forResource: "seed", withExtension: ".realm")
print("The bundled realm URL is: \(realmURL)")
// When you use the `seedFilePath` parameter, this copies the
// realm at the specified path for use with the user's config
newUserConfig.seedFilePath = realmURL
// Open the synced realm, downloading any changes before opening it.
// This starts with the existing data in the bundled realm, but checks
// for any updates to the data before opening it in your application.
let realm = try await Realm(configuration: newUserConfig, downloadBeforeOpen: .always)
print("Successfully opened the bundled realm")
// Read and write to the bundled realm as normal
let todos = realm.objects(Todo.self)
// There should be one todo whose owner is Daenerys because that's
// what was in the bundled realm.
var daenerysTodos = todos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysTodos.count, 1)
print("The bundled realm has \(daenerysTodos.count) todos whose owner is Daenerys")
// Write as usual to the realm, and see the object count increment
let todo = Todo(value: ["name": "Banish Ser Jorah", "owner": "Daenerys", "status": "In Progress"])
try realm.write {
realm.add(todo)
}
print("Successfully added a todo to the realm")
daenerysTodos = todos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysTodos.count, 2)
}

Nota

Diferencias entre los dominios sincronizados y los dominios solo locales

El ejemplo anterior usa SyncConfiguration para configurar un dominio sincronizado. Para crear una copia de un dominio local, configure su dominio con Realm.Configuration.

Volver

Eliminar un reino

En esta página