Cuando abres un reino, puedes pasar un Realm.Configuration, que especifica detalles adicionales sobre cómo configurar el archivo de dominio. Esto incluye aspectos como:
Pase una URL de archivo o un identificador en memoria para personalizar cómo se almacena el dominio en el dispositivo
Proporcione un usuario que haya iniciado sesión y detalles de sincronización para usar la sincronización con el reino
Especifique que el reino utilice solo un subconjunto de las clases de su aplicación
Si es necesario compactar un reino para reducir su tamaño de archivo y cuándo hacerlo
Pase una clave de cifrado para cifrar un reino
Proporcionar una versión del esquema o un bloque de migración al realizar cambios en el esquema
Tip
Esta página cubre cómo abrir un archivo realm que no sincroniza datos. Si desea utilizar Sincronización de dispositivos para sincronizar datos con otros dispositivos, consulte: Configurar y abrir un Realm sincronizado.
Abrir un reino sin sincronización
Puede abrir un reino local no sincronizado con varias opciones de configuración diferentes:
Sin configuración, es decir, configuración predeterminada
Especifique una URL de archivo para el reino
Abra el reino solo en la memoria, sin guardar un archivo en el sistema de archivos
Copiar un reino sincronizado para usarlo sin sincronización
Abre un Realm por defecto o un Realm en una URL de archivo
Puedes abrir el realm por defecto con +[RLMRealm defaultRealm].
También puede pasar un objeto RLMRealmConfiguration a +[RLMRealm realmWithConfiguration:error:] para abrir un reino en una URL de archivo específica, en la memoria o con Device Sync.
Puede establecer la configuración de reino predeterminada pasando una instancia de RLMRealmConfiguration a +[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];
Puedes abrir un reino con el inicializador Realm(). Si omites el parámetro Realm.Configuration, se abrirá el reino predeterminado.
Puede establecer la configuración de reino predeterminada asignando una nueva instancia de Realm.Configuration a la propiedad de clase 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 un reino en memoria
Cambiado en la 10.46.0 versión: Admite la apertura de una base de datos sincronizada en la memoria.
Puedes abrir un reino completamente en la memoria, lo que no creará un
.realm Archivo o sus archivos auxiliares asociados. En su lugar, el SDK almacena objetos en memoria mientras el dominio está abierto y los descarta inmediatamente cuando se cierran todas las instancias.
Tenga en cuenta que esta propiedad no se puede combinar con fileURL. En las versiones 10.45.3 y anteriores del SDK de Swift, esta propiedad no se puede combinar con syncConfiguration.
Establezca la propiedad inMemoryIdentifier de la configuración del reino.
// 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];
Establezca la propiedad inMemoryIdentifier de la configuración del reino.
// 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
Cuando todas las instancias de dominio en memoria con un identificador específico quedan fuera del alcance, Realm elimina todos los datos de ese dominio. Para evitar esto, mantenga una referencia sólida a cualquier dominio en memoria durante el ciclo de vida de su aplicación.
Abra un reino con funciones de concurrencia rápida
Puede utilizar la sintaxis async/await de Swift para abrir un reino aislado de MainActor o especificar un actor al abrir un reino de forma asincrónica:
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) }
O puede definir un actor de reino personalizado para administrar todas las operaciones de su reino:
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 } }
Un reino aislado del actor se puede utilizar con actores locales o globales.
// 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 obtener más información sobre cómo trabajar con reinos aislados de actores, consulte Usar reino con actores - Swift SDK.
Cerrar un reino
No es necesario cerrar manualmente un dominio en Swift ni Objective-C. Cuando un dominio queda fuera del alcance y se elimina de la memoria debido a ARC, el reino está cerrado.
Gestionar errores al acceder a un Realm
Para manejar errores al acceder a un reino, proporcione un puntero NSError al 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 manejar errores al acceder a un reino, utilice el mecanismo de manejo de errores integrado de Swift:
do { let realm = try Realm() // Use realm } catch let error as NSError { // Handle error }
Proporcionar un subconjunto de clases a un reino
Tip
Operar con bajas restricciones de memoria
Algunas aplicaciones, como las de watchOS y las extensiones de iOS, tienen restricciones estrictas en su consumo de memoria. Para optimizar su modelo de datos para entornos con poca memoria, abra el dominio con un subconjunto de clases.
De forma predeterminada, el SDK de Swift añade automáticamente al esquema del dominio todas las clases derivadas de RLMObjecty RLMEmbeddedObjectde su ejecutable. Puede controlar qué objetos se añaden configurando la propiedad objectClasses del 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 }
De forma predeterminada, el SDK de Swift añade automáticamente al esquema del dominio todas las clases derivadas de Objecty EmbeddedObject de su ejecutable. Puede controlar qué objetos se añaden configurando la propiedad objectTypes del 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 propiedades mediante las API de Realm
Puedes definir propiedades cuyos valores se inicializan mediante las API de Realm. Por ejemplo:
class SomeSwiftType { let persons = try! Realm().objects(Person.self) // ... }
Si este código de inicialización se ejecuta antes de configurar el dominio, podría experimentar un comportamiento inesperado. Por ejemplo, si establece un bloqueo de migración para la configuración predeterminada del dominio applicationDidFinishLaunching() en, pero crea una instancia de SomeSwiftType antes applicationDidFinishLaunching() de, podría acceder al dominio antes de que se haya configurado correctamente.
Para evitar estos problemas, considere realizar una de las siguientes acciones:
Aplaza la creación de instancias de cualquier tipo que inicialice con entusiasmo propiedades mediante las API de Realm hasta que tu aplicación haya terminado de configurar sus configuraciones de reino.
Define tus propiedades con la palabra clave
lazyde Swift. Esto te permite instanciar estos tipos de forma segura en cualquier momento del ciclo de vida de tu aplicación, siempre y cuando no intentes acceder a tus propiedadeslazyhasta que tu aplicación haya configurado su dominio.Inicialice sus propiedades únicamente mediante las API de Realm que acepten explícitamente las configuraciones definidas por el usuario. Puede estar seguro de que los valores de configuración que utiliza se han configurado correctamente antes de usarlos para abrir los reinos.
Usar Realm cuando el dispositivo esté bloqueado
De forma predeterminada, iOS 8 y versiones posteriores cifran los archivos de la aplicación con NSFileProtection cuando el dispositivo está bloqueado. Si la aplicación intenta acceder a un dominio mientras el dispositivo está bloqueado, podría aparecer el siguiente error:
open() failed: Operation not permitted
Para gestionar esto, reduzca la protección de archivos de la carpeta que contiene los archivos de Realm. Un nivel de protección menos estricto como NSFileProtectionCompleteUntilFirstUserAuthentication permite el acceso a los archivos incluso cuando el dispositivo está bloqueado.
Tip
Si desea reducir el cifrado de archivos de iOS, considere utilizar el cifrado integrado de Realm para proteger sus datos.
Este ejemplo muestra cómo aplicar un nivel de protección menos estricto al directorio principal del dominio predeterminado.
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)
Realm puede crear y eliminar archivos auxiliares en cualquier momento. En lugar de reducir la protección de los archivos, aplíquela a la carpeta principal. De esta forma, la protección se aplica a todos los archivos relevantes, independientemente de su fecha de creación.