Docs Menu
Docs Home
/ /
Archivos del reino

Configura y abre un Realm - SDK de Swift

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.

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

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)

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.

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:

@MainActor
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
@globalActor actor BackgroundActor: GlobalActor {
static var shared = BackgroundActor()
}
@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)")
}
@MainActor
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.

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.

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
}

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)

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 lazy de 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 propiedades lazy hasta 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.

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.

Volver

Archivos del reino

En esta página