Configurar e abrir um domínio - Swift SDK
Nesta página
- Abra um Realm sem sincronização
- Abrir um Realm padrão ou Realm em uma URL de arquivo
- Abrir um Realm na memória
- Abra um Realm com recursos de simultaneidade Swift
- Fechar um Realm
- Lidar com erros ao acessar um Realm
- Fornecer um subconjunto de classes para um Realm
- Inicializar propriedades usando APIs de domínio
- Use Realm quando o dispositivo estiver bloqueado
Ao abrir um Realm, você pode passar uma Realm.Configuration que especifica detalhes adicionais sobre como configurar o arquivo Realm . Isso inclui coisas como:
Passe um arquivo de URL ou identificador in-memory para personalizar como o domínio é armazenado no dispositivo
Fornece um usuário conectado e detalhes de sincronização para usar a sincronização com o real
Especifique o domínio para usar apenas um subconjunto das classes do seu aplicativo
Se e quando compactar um domínio para reduzir o tamanho do arquivo
Passe uma chave de encriptação para criptografar um Realm
Forneça uma versão do esquema ou bloco de migração ao fazer alterações no esquema
Dica
Veja também:
Esta página aborda como abrir um arquivo de área que não sincroniza dados. Se você quiser usar o Device Sync para sincronizar dados com outros dispositivos, consulte: Configurar & Abrir um Realm sincronizado.
Abra um Realm sem sincronização
Você pode abrir um domínio local não sincronizado com várias opções de configuração diferentes:
Nenhuma configuração - ou seja, configuração padrão
Especifique um URL de arquivo para o domínio
Abra o domínio somente na memória, sem salvar um arquivo no sistema de arquivos
Copie um domínio sincronizado para usar sem Sincronizar
Abrir um Realm padrão ou Realm em uma URL de arquivo
Você pode abrir o Realm padrão com +[RLMRealm defaultRealm].
Você também pode passar um objeto RLMRealmConfiguration para +[RLMRealm realmWithConfiguration:error:] para abrir um Realm em um URL de arquivo específico, na memória ou com o Device Sync.
Você pode definir a configuração de Realm padrão passando uma instância RLMRealmConfiguration para +[RLMRealmConfiguration setDefaultConfiguration:].
// Open the default realm RLMRealm *defaultRealm = [RLMRealm defaultRealm]; // Open the realm with a specific file URL, for example a username NSString *username = @"GordonCole"; RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration]; configuration.fileURL = [[[configuration.fileURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:username] URLByAppendingPathExtension:@"realm"]; NSError *error = nil; RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:&error];
Você pode abrir um realm com o Inicializador Realm(). Se você omitir o parâmetro Realm.Configuration, abrirá o realm padrão.
Você pode definir a configuração de domínio padrão atribuindo uma nova instância Realm.Configuration à propriedade de classe Realm.Configuration.defaultConfiguration .
// Open the default realm let defaultRealm = try! Realm() // Open the realm with a specific file URL, for example a username let username = "GordonCole" var config = Realm.Configuration.defaultConfiguration config.fileURL!.deleteLastPathComponent() config.fileURL!.appendPathComponent(username) config.fileURL!.appendPathExtension("realm") let realm = try! Realm(configuration: config)
Abrir um Realm na memória
Alterado na versão 10.46.0: Suporta a abertura de um banco de dados sincronizado na memória.
Você pode abrir um Realm inteiramente na memória, que não criará um arquivo .realm
ou seus arquivos auxiliares associados. Em vez disso, o SDK armazena objetos na memória enquanto o Realm está aberto e os descarta imediatamente quando todas as instâncias são fechadas.
Observe que esta propriedade não pode ser combinada com fileURL
. Nas versões 10.45.3 e anteriores do Swift SDK, esta propriedade não pode ser combinada com syncConfiguration
.
Defina a propriedade inMemoryIdentifier da configuração do domínio.
// Open the realm with a specific in-memory identifier. NSString *identifier = @"MyRealm"; RLMRealmConfiguration *configuration = [[RLMRealmConfiguration alloc] init]; configuration.inMemoryIdentifier = identifier; // Open the realm RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:nil];
Defina a propriedade inMemoryIdentifier da configuração do domínio.
// Open the realm with a specific in-memory identifier. let identifier = "MyRealm" let config = Realm.Configuration( inMemoryIdentifier: identifier) // Open the realm let realm = try! Realm(configuration: config)
Importante
Quando todas as instâncias do domínio na memória com um identificador específico saem do escopo, o Realm exclui todos os dados nesse domínio. Para evitar isso, mantenha uma forte referência a quaisquer regiões na memória durante a vida útil do seu aplicativo.
Abra um Realm com recursos de simultaneidade Swift
Você pode usar a sintaxe async/await do Swift para abrir um reino isolado do MainActor ou especificar um ator ao abrir um reino de forma assíncrona:
func mainThreadFunction() async throws { // These are identical: the async init produces a // MainActor-isolated Realm if no actor is supplied let realm1 = try await Realm() let realm2 = try await Realm(actor: MainActor.shared) try await useTheRealm(realm: realm1) }
Ou você pode definir um ator de reino personalizado para managed todas as suas operações de domínio:
actor RealmActor { // An implicitly-unwrapped optional is used here to let us pass `self` to // `Realm(actor:)` within `init` var realm: Realm! init() async throws { realm = try await Realm(actor: self) } var count: Int { realm.objects(Todo.self).count } func createTodo(name: String, owner: String, status: String) async throws { try await realm.asyncWrite { realm.create(Todo.self, value: [ "_id": ObjectId.generate(), "name": name, "owner": owner, "status": status ]) } } func getTodoOwner(forTodoNamed name: String) -> String { let todo = realm.objects(Todo.self).where { $0.name == name }.first! return todo.owner } struct TodoStruct { var id: ObjectId var name, owner, status: String } func getTodoAsStruct(forTodoNamed name: String) -> TodoStruct { let todo = realm.objects(Todo.self).where { $0.name == name }.first! return TodoStruct(id: todo._id, name: todo.name, owner: todo.owner, status: todo.status) } func updateTodo(_id: ObjectId, name: String, owner: String, status: String) async throws { try await realm.asyncWrite { realm.create(Todo.self, value: [ "_id": _id, "name": name, "owner": owner, "status": status ], update: .modified) } } func deleteTodo(id: ObjectId) async throws { try await realm.asyncWrite { let todoToDelete = realm.object(ofType: Todo.self, forPrimaryKey: id) realm.delete(todoToDelete!) } } func close() { realm = nil } }
Um realm isolado de ator pode ser usado com atores locais ou globais.
// A simple example of a custom global actor actor BackgroundActor: GlobalActor { static var shared = BackgroundActor() } func backgroundThreadFunction() async throws { // Explicitly specifying the actor is required for anything that is not MainActor let realm = try await Realm(actor: BackgroundActor.shared) try await realm.asyncWrite { _ = realm.create(Todo.self, value: [ "name": "Pledge fealty and service to Gondor", "owner": "Pippin", "status": "In Progress" ]) } // Thread-confined Realms would sometimes throw an exception here, as we // may end up on a different thread after an `await` let todoCount = realm.objects(Todo.self).count print("The number of Realm objects is: \(todoCount)") } func mainThreadFunction() async throws { try await backgroundThreadFunction() }
Para obter mais informações sobre como trabalhar com domínios isolados por atores, consulte Use Realm with Actors - Swift SDK.
Fechar um Realm
Não é necessário fechar manualmente um Realm no Swift ou Objective-C. Quando um Realm sai do escopo e é removido da memória devido ao ARC, o Realm é fechado.
Lidar com erros ao acessar um Realm
Para lidar com erros ao acessar um domínio, forneça um ponteiro NSError
para o parâmetro error
:
NSError *error = nil; RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error]; if (!realm) { // Handle error return; } // Use realm
Para lidar com erros ao acessar um realm, use o mecanismo integrado de tratamento de erros do Swift:
do { let realm = try Realm() // Use realm } catch let error as NSError { // Handle error }
Fornecer um subconjunto de classes para um Realm
Dica
Operando com restrições de memória baixas
Alguns aplicativos, como os aplicativos do watchOS e as extensões de aplicativos do iOS, têm restrições rígidas quanto ao espaço ocupado na memória. Para otimizar seu modelo de dados para ambientes de baixa memória, abra o domínio com um subconjunto de classes.
Por padrão, o Swift SDK adiciona automaticamente todas as classes derivadas de RLMObject- e RLMEmbeddedObjectem seu executável ao Realm Schema. Você pode controlar quais objetos são adicionados definindo a propriedade objectClasses do objeto RLMRealmConfiguration .
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; // Given a RLMObject subclass called `Task` // Limit the realm to only the Task object. All other // Object- and EmbeddedObject-derived classes are not added. config.objectClasses = @[[Task class]]; NSError *error = nil; RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error]; if (error != nil) { // Something went wrong } else { // Use realm }
Por padrão, o Swift SDK adiciona automaticamente todas as classes derivadas de Objeto e EmbeddedObject em seu executável ao Realm Schema. Você pode controlar quais objetos são adicionados definindo a propriedade objectTypes do objeto Realm.Configuration.
var config = Realm.Configuration.defaultConfiguration // Given: `class Dog: Object` // Limit the realm to only the Dog object. All other // Object- and EmbeddedObject-derived classes are not added. config.objectTypes = [Dog.self] let realm = try! Realm(configuration: config)
Inicializar propriedades usando APIs de domínio
Você pode definir propriedades cujos valores são inicializados usando APIs do Realm. Por exemplo:
class SomeSwiftType { let persons = try! Realm().objects(Person.self) // ... }
Se esse código de inicialização for executado antes de você definir as configurações do Realm, poderá ocorrer um comportamento inesperado. Por exemplo, se você definir um bloco de migração para a configuração padrão do Realm em applicationDidFinishLaunching()
, mas criar uma instância de SomeSwiftType
antes de applicationDidFinishLaunching()
, poderá estar acessando o Realm antes que ele tenha sido configurado corretamente.
Para evitar esses problemas, considere fazer o seguinte:
Adie a instanciação de qualquer tipo que inicialize propriedades usando APIs do Realm até que seu aplicativo tenha concluído a definição das configurações de seu domínio.
Defina suas propriedades usando a palavra-chave
lazy
do Swift. Isso permite que você instantiate esses tipos com segurança a qualquer momento durante o ciclo de vida do aplicativo, desde que você não tente acessar suas propriedades delazy
enquanto o aplicativo não tiver definido suas configurações de domínio.Inicialize suas propriedades somente usando APIs de Realm que aceitam explicitamente configurações definidas pelo usuário. Você pode ter certeza de que os valores de configuração que você está usando foram estabelecidos corretamente antes de serem usados para abrir domínios.
Use Realm quando o dispositivo estiver bloqueado
Por padrão, o iOS 8 e superior criptografam os arquivos do aplicativo usando o NSFileProtection
sempre que o dispositivo estiver bloqueado. Se seu aplicativo tentar acessar um território enquanto o dispositivo estiver bloqueado, você poderá ver o seguinte erro:
open() failed: Operation not permitted
Para lidar com isso, faça downgrade da proteção de arquivos da pasta que contém os arquivos do Realm. Um nível de proteção menos rigoroso, como NSFileProtectionCompleteUntilFirstUserAuthentication, permite o acesso ao arquivo mesmo quando o dispositivo está bloqueado.
Dica
Se você reduzir a criptografia de arquivos do iOS, considere usar a criptografia integrada do Realm para proteger seus dados.
Este exemplo mostra como aplicar um nível de proteção menos rigoroso ao diretório pai do Realm padrão.
let realm = try! Realm() // Get the realm file's parent directory let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().path // Disable file protection for this directory after the user has unlocked the device once try! FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication], ofItemAtPath: folderPath)
O Realm pode criar e excluir arquivos auxiliares a qualquer momento. Em vez de fazer downgrade da proteção de arquivos nos arquivos, aplice-a à pasta principal. Dessa forma, a proteção de arquivos se aplica a todos os arquivos relevantes, independentemente do tempo de criação.