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:
Pasa un fileURL o un identificador en memoria para personalizar cómo se almacena el realm en el dispositivo
Provide a logged-in user and Sync details to use Sync with the realm
Especifica el realm de uso solo para un subconjunto de las clases de tu aplicación
Si es necesario compactar un reino para reducir su tamaño de archivo y cuándo hacerlo
Pass an encryption key to encrypt a realm
Proporciona una versión de 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.
Open a Realm Without Sync
You can open a non-synced local realm with several different configuration options:
Sin configuración (es decir, configuración por defecto)
Especifica una URL de archivo para el realm
Abre el realm solo en memoria, sin guardar un archivo en el sistema de archivos
Copy a synced realm to use without Sync
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 predeterminada del realm 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];
You can open a realm with the Realm() initializer. If you omit the Realm.Configuration parameter, you will open the default realm.
You can set the default realm configuration by assigning a new Realm.Configuration instance to the Realm.Configuration.defaultConfiguration class property.
// 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)
Open an In-Memory Realm
Cambiado en la versión 10.46.0: Ofrece soporte para abrir una base de datos sincronizada en 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.
Note that this property cannot be combined with fileURL. In Swift SDK versions 10.45.3 and earlier, this property cannot be combined with 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
When all in-memory realm instances with a particular identifier go out of scope, Realm deletes all data in that realm. To avoid this, hold onto a strong reference to any in-memory realms during your app's lifetime.
Open a Realm with Swift Concurrency Features
Puede utilizar la sintaxis async/await de Swift para abrir un realm aislado en MainActor o especificar un actor al abrir un realm de forma así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) }
Or you can define a custom realm actor to manage all of your realm operations:
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 } }
An actor-isolated realm may be used with either local or global actors.
// 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() }
For more information about working with actor-isolated realms, refer to Use Realm with Actors - Swift SDK.
Close a Realm
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
To handle errors when accessing a realm, provide an NSError pointer to the error parameter:
NSError *error = nil; RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error]; if (!realm) { // Handle error return; } // Use realm
To handle errors when accessing a realm, use Swift's built-in error handling mechanism:
do { let realm = try Realm() // Use realm } catch let error as NSError { // Handle error }
Proporcionar un subconjunto de clases a un reino
Tip
Operating with Low Memory Constraints
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 }
By default, the Swift SDK automatically adds all Object- and EmbeddedObject-derived classes in your executable to the realm schema. You can control which objects get added by setting the objectTypes property of the Realm.Configuration object.
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 utilizando las API de Realm
You might define properties whose values are initialized using Realm APIs. For example:
class SomeSwiftType { let persons = try! Realm().objects(Person.self) // ... }
If this initialization code runs before you set up your Realm configurations, you might get unexpected behavior. For example, if you set a migration block for the default realm configuration in applicationDidFinishLaunching(), but you create an instance of SomeSwiftType before applicationDidFinishLaunching(), you might be accessing your realm before it has been correctly configured.
To avoid such issues, consider doing one of the following:
Defer instantiation of any type that eagerly initializes properties using Realm APIs until after your app has completed setting up its realm configurations.
Define your properties using Swift's
lazykeyword. This allows you to safely instantiate such types at any time during your application's lifecycle, as long as you do not attempt to access yourlazyproperties until after your app has set up its realm configurations.Only initialize your properties using Realm APIs that explicitly take in user-defined configurations. You can be sure that the configuration values you are using have been set up properly before they are used to open realms.
Use Realm When the Device Is Locked
By default, iOS 8 and above encrypts app files using NSFileProtection whenever the device is locked. If your app attempts to access a realm while the device is locked, you might see the following 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
If you reduce iOS file encryption, consider using Realm's built-in encryption to secure your data instead.
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.