Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ /

Agrupar um arquivo Realm - Swift SDK

Nesta página

  • Visão geral
  • Criar um arquivo Realm para agrupamento
  • Agrupe um arquivo Realm em seu aplicativo de produção
  • Abrir um Realm a partir de um arquivo de Realm agrupado

Observação

Agrupar domínios sincronizados

Swift SDK versão 10.23.0 introduziu a capacidade de agrupar domínios sincronizados. Antes da versão 10.23.0, só era possível agrupar domínios locais.

O Realm suporta o agrupamento de arquivos realm. Ao agrupar um arquivo de domínio, você inclui um banco de dados e todos os seus dados no download do aplicativo.

Isso permite que os usuários iniciem aplicativos pela primeira vez com um conjunto de dados iniciais. Para domínios sincronizados, o agrupamento pode evitar um download inicial demorado na primeira vez que um usuário abre seu aplicativo. Em vez disso, os usuários só precisam baixar as alterações sincronizadas que ocorreram desde que você gerou o arquivo agrupado.

Importante

Agrupar domínios sincronizados

If your backend application uses Flexible Sync, users could experience a client reset the first time they open the bundled realm file. This can occur when client maximum offline time is enabled (client maximum offline time is enabled by default). If the bundled realm file was generated more than the number of days specified by the client maximum offline time setting before the user syncs for the first time, the user experiences a client reset.

Os aplicativos que executam uma redefinição do cliente baixam o estado completo do domínio do backend do aplicativo. Isso nega as vantagens de agrupar um arquivo de domínio. Para evitar o reinício do cliente e preservar as vantagens do agrupamento de arquivos realm:

  • Evite usar o tempo offline máximo do cliente em aplicativos que agrupam um domínio sincronizado.

  • Se o seu aplicativo usar o tempo máximo offline do cliente, certifique-se de que o download do aplicativo sempre inclua um arquivo de domínio sincronizado recentemente. Gere um novo arquivo a cada versão do aplicativo e garanta que nenhuma versão permaneça atual por mais do que o número máximo de dias de tempo offline do cliente .

Para criar e agrupar um arquivo de domínio com seu aplicativo:

  1. Crie um arquivo de domínio que contenha os dados que você deseja agrupar.

  2. Agrupe o arquivo realm em seu aplicativo de produção.

  3. Em seu aplicativo de produção, abra o domínio a partir do arquivo de ativos agrupados. Para domínios sincronizados, você deve fornecer a chave de partição.

  1. Construa um aplicativo de domínio temporário que compartilhe o modelo de dados do seu aplicativo.

  2. Abra um domínio e adicione os dados que deseja agrupar. Se estiver usando um domínio sincronizado, dê tempo para que o domínio sincronize totalmente.

  3. Use o método writeCopy(configuration:) para copiar o domínio para um novo arquivo:

Dica

Se a sua aplicação acessar Realm em um contexto do async/await, marque o código com @MainActor para evitar falhas relacionadas a threading.

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 automaticamente seu domínio no menor tamanho possível antes de copiar.

Observação

Diferenças entre domínios sincronizados e domínios somente locais

O exemplo acima utiliza um SyncConfiguration para configurar um realm sincronizado. Para criar uma cópia de um realm local, configure seu realm com RealmConfiguration .

Agora que você tem uma cópia do domínio que contém os dados iniciais, agrupe-o com seu aplicativo de produção. Em um nível amplo, isso implica:

  1. Crie um novo projeto com os mesmos modelos de dados exatos que seu aplicativo de produção. Abra um domínio e adicione os dados que deseja agrupar. Como os arquivos realm são multiplataforma, você pode fazer isso em um aplicativo macOS.

  2. Arraste a cópia compactada do seu arquivo de área para o Xcode Project Navigator do seu aplicativo de produção.

  3. Go para a aba Build Phases do destino do aplicativo no Xcode. Adicione o arquivo de domínio à fase de construção Copy Bundle Resources .

  4. Neste ponto, seu aplicativo pode acessar o arquivo de domínio agrupado. Encontre seu caminho com Bundle.main.path(forResource:ofType).

Você pode abrir o domínio diretamente no caminho do pacote se a propriedade readOnly estiver definida como true no Realm.Configuration. Se você deseja modificar o domínio agrupado, primeiro copie o arquivo agrupado para a pasta Documentos do seu aplicativo com a configuração seedFilePath com a URL do domínio Realm em sua Configuração.

Dica

Veja o aplicativo de amostra de migração para um aplicativo de trabalho completo que usa um domínio local agrupado.

Agora que você tem uma cópia do domínio incluída em seu aplicativo de produção, precisa adicionar código para usá-lo. Use o método seedFilePath ao configurar seu domínio para abrir o domínio a partir do arquivo agrupado:

Dica

Se a sua aplicação acessar Realm em um contexto do async/await, marque o código com @MainActor para evitar falhas relacionadas a threading.

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)
}

Observação

Diferenças entre domínios sincronizados e domínios somente locais

O exemplo acima utiliza um SyncConfiguration para configurar um realm sincronizado. Para criar uma cópia de um realm local, configure seu realm com Realm.Configuration .

Voltar

Excluir um realm

Próximo

Reduzir o tamanho do arquivo de domínio