Definir un nuevo tipo de objeto
Puedes definir un objeto Realm derivando de Clase RLMObject o RLMEmbeddedObject. El nombre de la clase se convierte en el nombre de la tabla en el dominio, y sus propiedades persisten en la base de datos. Esto facilita el trabajo con objetos persistentes tanto como con objetos Objective-C normales.
// A dog has an _id primary key, a string name, an optional // string breed, and a date of birth. @interface Dog : RLMObject @property RLMObjectId *_id; @property NSString *name; @property NSString *breed; @property NSDate *dateOfBirth; @end @implementation Dog + (NSString *)primaryKey { return @"_id"; } + (NSArray<NSString *> *)requiredProperties { return @[ @"_id", @"name", @"dateOfBirth" ]; } @end
Puedes definir un objeto Realm derivando de la clase Object o EmbeddedObject. El nombre de la clase se convierte en el nombre de la tabla en el reino, y sus propiedades persisten en la base de datos. Esto facilita el trabajo con objetos persistentes tanto como con objetos Swift normales.
// A dog has an _id primary key, a string name, an optional // string breed, and a date of birth. class Dog: Object { (primaryKey: true) var _id: ObjectId var name = "" var breed: String? var dateOfBirth = Date() }
Nota
Los nombres de clase están limitados a un máximo de 57 caracteres UTF-8.
Declarar propiedades
Al declarar los atributos de propiedad de una clase, se puede especificar si el dominio debe administrar dichas propiedades. Las propiedades administradas se almacenan o actualizan en la base de datos. Las propiedades ignoradas no se almacenan en la base de datos. Se pueden combinar propiedades administradas e ignoradas dentro de una clase.
La sintaxis para marcar propiedades como administradas o ignoradas varía según la versión del SDK que utilice.
Atributos de propiedad persistentes
Novedades en la 10.10.0 versión: El @Persisted El estilo de declaración reemplaza @objc dynamic RealmOptionallas RealmProperty notaciones, y de versiones anteriores del SDK. Para una versión anterior del SDK, consulte: Atributos de propiedades dinámicas de Objective-C.
Declare las propiedades del modelo que desea almacenar en la base de datos como @Persisted. Esto les permite acceder a los datos subyacentes de la base de datos.
Cuando se declara cualquier propiedad como @Persisted dentro de una clase, las demás propiedades dentro de esa clase se ignoran automáticamente.
Si mezcla declaraciones de propiedades @Persisted y @objc dynamic dentro de una definición de clase, se ignorarán todos los atributos de propiedad marcados como @objc dynamic.
Tip
Nuestra página de Tipos de propiedad admitidos contiene una hoja de referencia para la declaración de propiedad.
Atributos de propiedades dinámicas de Objective-C
Cambiado en la 10.10.0 versión: Esta información de declaración de propiedad es para versiones del SDK anteriores 10.10.0 a.
Declarar propiedades dinámicas del modelo Realm en el entorno de ejecución de Objective-C. Esto les permite acceder a los datos de la base de datos subyacente.
Puedes:
Utiliza
@objc dynamic varpara declarar propiedades individualesUtilice
@objcMemberspara declarar una clase. Luego, declare las propiedades individuales condynamic var.
Utilice let para declarar LinkingObjects, List, RealmOptional y RealmProperty. El entorno de ejecución de Objective-C no puede representar estas propiedades genéricas.
Cambiado en la 10.8.0 versión: RealmProperty reemplaza a RealmOptional
Tip
Nuestra página de Tipos de propiedad admitidos contiene una hoja de referencia para la declaración de propiedad.
Tip
Para obtener una referencia sobre qué tipos admite Realm para usar como propiedades, consulte Tipos de propiedades admitidos.
Al declarar propiedades no genéricas, utilice la anotación @Persisted. El atributo @Persisted convierte las propiedades del modelo Realm en descriptores de acceso para los datos de la base de datos subyacente.
Declare propiedades en su tipo de objeto como lo haría en una interfaz Objective-C normal.
Para utilizar su interfaz en un arreglo de Realm, pase el nombre de su interfaz a la macro RLM_COLLECTION_TYPE(). Puedes colocar esto en la parte inferior del archivo de encabezado de tu interfaz. La macro RLM_COLLECTION_TYPE() crea un protocolo que permite etiquetar RLMArray con su tipo:
// Task.h @interface Task : RLMObject @property NSString *description; @end // Define an RLMArray<Task> type RLM_COLLECTION_TYPE(Task) // User.h // #include "Task.h" @interface User : RLMObject @property NSString *name; // Use RLMArray<Task> to have a list of tasks // Note the required double tag (<Task *><Task>) @property RLMArray<Task *><Task> *tasks; @end
Al declarar propiedades no genéricas, use la anotación @objc dynamic
var. El atributo @objc dynamic var convierte las propiedades del modelo Realm en descriptores de acceso para los datos de la base de datos subyacente. Si la clase se declara como @objcMembers (Swift 4 o posterior), puede declarar propiedades como dynamic var sin @objc.
Para declarar propiedades de los tipos genéricos LinkingObjects, List y RealmProperty, utilice let. Las propiedades genéricas no se pueden representar en el entorno de ejecución de Objective-C, que Realm utiliza para el envío dinámico de propiedades dinámicas.
Nota
Los nombres de propiedad están limitados a un máximo de 63 caracteres UTF-8.
Especificar una propiedad opcional/obligatoria
Puede declarar propiedades como opcionales u obligatorias (no opcionales) utilizando la sintaxis Swift estándar.
class Person: Object { // Required string property var name = "" // Optional string property var address: String? // Required numeric property var ageYears = 0 // Optional numeric property var heightCm: Float? }
Para declarar una propiedad determinada como requerida, implemente el método requiredProperties y devuelva una matriz de nombres de propiedades requeridas.
@interface Person : RLMObject // Required property - included in `requiredProperties` // return value array @property NSString *name; // Optional string property - not included in `requiredProperties` @property NSString *address; // Required numeric property @property int ageYears; // Optional numeric properties use NSNumber tagged // with RLMInt, RLMFloat, etc. @property NSNumber<RLMFloat> *heightCm; @end @implementation Person // Specify required pointer-type properties here. // Implicitly required properties (such as properties // of primitive types) do not need to be named here. + (NSArray<NSString *> *)requiredProperties { return @[@"name"]; } @end
Cambiado en la 10.8.0 versión: RealmProperty reemplaza a RealmOptional
Puedes declarar las propiedades String, Date, Data, y ObjectId como opcionales o requeridas (no opcionales) usando la sintaxis estándar de Swift. Declara tipos numéricos opcionales utilizando el tipo RealmProperty.
class Person: Object { // Required string property @objc dynamic var name = "" // Optional string property @objc dynamic var address: String? // Required numeric property @objc dynamic var ageYears = 0 // Optional numeric property let heightCm = RealmProperty<Float?>() }
RealmProperty admite Int, Float, Double, Bool y todas las versiones de tamaño de Int (Int8, Int16, Int32, Int64).
Especificar una clave principal
Puede designar una propiedad como la llave primaria de su clase.
Las claves principales le permiten buscar, actualizar e insertar objetos de manera eficiente.
Las claves primarias están sujetas a las siguientes limitaciones:
Puede definir solo una clave principal por modelo de objeto.
Los valores de clave principal deben ser únicos en todas las instancias de un objeto en un dominio. El dominio genera un error si se intenta insertar un valor de clave principal duplicado.
Los valores de la llave primaria son inmutables. Para cambiar el valor de la clave primaria de un objeto, se debe borrar el objeto original e insertar uno nuevo con un valor de clave primaria diferente.
Los objetos incrustados no pueden definir una clave principal.
Declare la propiedad con primaryKey: true en la @Persisted notación para establecer la clave principal del modelo.
class Project: Object { (primaryKey: true) var id = 0 var name = "" }
Anule +[RLMObject primaryKey] para establecer la clave principal del modelo.
@interface Project : RLMObject @property NSInteger id; // Intended primary key @property NSString *name; @end @implementation Project // Return the name of the primary key property + (NSString *)primaryKey { return @"id"; } @end
Anule Object.primaryKey() para establecer la clave principal del modelo.
class Project: Object { @objc dynamic var id = 0 @objc dynamic var name = "" // Return the name of the primary key property override static func primaryKey() -> String? { return "id" } }
Indexar una propiedad
Puedes crear un índice en una propiedad específica de tu modelo. Los índices aceleran las consultas mediante los operadores de igualdad e IN. Reducen ligeramente la velocidad de las operaciones de inserción y actualización. Los índices utilizan memoria y ocupan más espacio en el archivo realm. Cada entrada de índice tiene un mínimo de 12 bytes. Se recomienda agregar índices solo cuando se optimiza el rendimiento de lectura para situaciones específicas.
Realm admite la indexación de propiedades de cadena, entero, booleano, Date, UUID, ObjectId y AnyRealmValue.
Novedades en la 10.8.0 versión: UUID AnyRealmValue tipos y
Para indexar una propiedad, declare la propiedad con indexed:true en la @Persisted notación.
class Book: Object { var priceCents = 0 (indexed: true) var title = "" }
Para indexar una propiedad, anule +[RLMObject indexedProperties] y devuelva una lista de nombres de propiedades indexadas.
@interface Book : RLMObject @property int priceCents; @property NSString *title; @end @implementation Book // Return a list of indexed property names + (NSArray *)indexedProperties { return @[@"title"]; } @end
Para indexar una propiedad, anule Object.indexedProperties() y devuelva una lista de nombres de propiedades indexadas.
class Book: Object { @objc dynamic var priceCents = 0 @objc dynamic var title = "" // Return a list of indexed property names override static func indexedProperties() -> [String] { return ["title"] } }
Ignorar una propiedad
Las propiedades ignoradas se comportan igual que las propiedades normales. No se pueden usar en consultas ni activan notificaciones de Realm. Aun así, puedes observarlas usando KVO.
Tip
Realm ignora automáticamente las propiedades de solo lectura.
Obsoleto desde la 10.10.0 versión: ignoredProperties()
Si no desea guardar un campo en su modelo en su ámbito, deje la notación @Persisted fuera del atributo de propiedad.
Además, si mezcla declaraciones de propiedades @Persisted y @objc dynamic dentro de una clase, se ignorarán las propiedades @objc dynamic.
class Person: Object { // If some properties are marked as @Persisted, // any properties that do not have the @Persisted // annotation are automatically ignored. var tmpId = 0 // The @Persisted properties are managed var firstName = "" var lastName = "" // Read-only properties are automatically ignored var name: String { return "\(firstName) \(lastName)" } // If you mix the pre-10.10 property declaration // syntax `@objc dynamic` with the 10.10+ @Persisted // annotation within a class, `@objc dynamic` // properties are ignored. @objc dynamic var email = "" }
Si no desea guardar un campo en su modelo en su ámbito, anule +[RLMObject ignoreProperties] y devuelva una lista de nombres de propiedades ignoradas.
@interface Person : RLMObject @property NSInteger tmpId; @property (readonly) NSString *name; // read-only properties are automatically ignored @property NSString *firstName; @property NSString *lastName; @end @implementation Person + (NSArray *)ignoredProperties { return @[@"tmpId"]; } - (NSString *)name { return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName]; } @end
Si no desea guardar un campo en su modelo en su ámbito, anule Object.ignoredProperties() y devuelva una lista de nombres de propiedades ignoradas.
class Person: Object { @objc dynamic var tmpId = 0 @objc dynamic var firstName = "" @objc dynamic var lastName = "" // Read-only properties are automatically ignored var name: String { return "\(firstName) \(lastName)" } // Return a list of ignored property names override static func ignoredProperties() -> [String] { return ["tmpId"] } }
Declarar propiedades Enum
Cambiado en la 10.10.0 versión: El protocolo ahora es en PersistableEnum lugar RealmEnum de.
Puede usar enumeraciones con @Persisted marcándolas como compatibles con el protocolo PersistableEnum. Un PersistableEnum puede ser cualquier RawRepresentable enumeración cuyo tipo sin formato sea compatible con Realm.
// Define the enum enum TaskStatusEnum: String, PersistableEnum { case notStarted case inProgress case complete } // To use the enum: class Task: Object { var name: String = "" var owner: String? // Required enum property var status = TaskStatusEnum.notStarted // Optional enum property var optionalTaskStatusEnumProperty: TaskStatusEnum? }
Realm solo admite enumeraciones @objc respaldadas por Int.
// Define the enum @objc enum TaskStatusEnum: Int, RealmEnum { case notStarted = 1 case inProgress = 2 case complete = 3 } // To use the enum: class Task: Object { @objc dynamic var name: String = "" @objc dynamic var owner: String? // Required enum property @objc dynamic var status = TaskStatusEnum.notStarted // Optional enum property let optionalTaskStatusEnumProperty = RealmProperty<TaskStatusEnum?>() }
Tip
Reasignar un nombre de propiedad
Nuevo en la versión 10.33.0.
Puedes asignar el nombre público de una propiedad en tu modelo de objetos a un nombre privado diferente para almacenarlo en el dominio. Esto podría ser útil si los nombres de propiedad de tu esquema de Device Sync usan la escritura en mayúsculas y minúsculas, por ejemplo, mientras que tu proyecto usa la escritura en mayúsculas y minúsculas típica de Swift.
Declare el nombre que desea usar en su proyecto como la propiedad @Persisted en el modelo de objetos. Luego, pase un diccionario con los valores públicos y privados de los nombres de las propiedades mediante la función propertiesMapping().
En este ejemplo, firstName es el nombre de la propiedad pública que usamos en el código del proyecto para realizar operaciones CRUD. Con la función propertiesMapping(), la asignamos para almacenar valores que usan la propiedad privada first_name en el dominio. Si escribimos en un dominio sincronizado, el esquema de sincronización ve los valores almacenados con la propiedad privada first_name.
class Person: Object { var firstName = "" var lastName = "" override class public func propertiesMapping() -> [String: String] { ["firstName": "first_name", "lastName": "last_name"] } }
Definir una proyección de clase
Acerca de estos ejemplos
Los ejemplos de esta sección utilizan un conjunto de datos simple. Los dos tipos de objeto Realm son Person y un objeto incrustado Address. Un Person contiene nombre y apellido, un Address opcional y una lista de amigos compuesta por otros Person objetos. Un Address contiene una ciudad y un país.
Vea el esquema de estas dos clases, Person y Address, a continuación:
class Person: Object { var firstName = "" var lastName = "" var address: Address? var friends = List<Person>() } class Address: EmbeddedObject { var city: String = "" var country = "" }
Cómo definir una proyección de clase
Nuevo en la versión 10.21.0.
Define una proyección de clase creando una clase de tipo Proyección.Especifica el objeto o el objeto incrustado base cuyas propiedades quieres usar en la proyección de clase. Usa el @Projected contenedor de propiedades para declarar una propiedad que quieras proyectar desde una @Persisted propiedad en el objeto base.
Nota
Cuando se utiliza una lista o un MutableSet en una proyección de clase, el tipo en la proyección de clase debe ser ProjectedCollection.
class PersonProjection: Projection<Person> { (\Person.firstName) var firstName // Passthrough from original object (\Person.address?.city) var homeCity // Rename and access embedded object property through keypath (\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String> // Collection mapping }
Cuando define una proyección de clase, puede transformar la propiedad original @Persisted de varias maneras:
Passthrough: la propiedad tiene el mismo nombre y tipo que el objeto original
Cambiar nombre: la propiedad tiene el mismo tipo que el objeto original, pero un nombre diferente
Resolución de ruta de clave: utilice la resolución de ruta de clave para acceder a las propiedades del objeto original, incluidas las propiedades del objeto incrustado
Mapeo de colecciones:Proyecta listas o conjuntos mutables de
Objects oEmbeddedObjects como una colección de valores primitivosExclusión: cuando se utiliza una proyección de clase, se excluyen las propiedades del objeto subyacente que no se proyectan a
@Projectedtravés de la proyección de clase. Esto permite observar cambios en una proyección de clase y no ver cambios en propiedades que no formen parte de la proyección de clase.
Definir un objeto asimétrico
Nuevo en la versión 10.29.0.
Si su aplicación usa Sincronización flexible, puede usar la ingesta de datos para sincronizar un objeto unidireccionalmente desde su dispositivo a la base de datos vinculada a su aplicación Atlas App Services. Defina un objeto asimétrico heredando de AsymmetricObject.
class WeatherSensor: AsymmetricObject { (primaryKey: true) var _id: ObjectId var deviceId: String var temperatureInFahrenheit: Float var barometricPressureInHg: Float var windSpeedInMph: Int }
Cambiado en la 10.42.4 versión: Los objetos asimétricos pueden vincularse a objetos no integrados.
AsymmetricObject Admite ampliamente los mismos tipos de propiedades que Object, con algunas excepciones:
- Los objetos asimétricos solo pueden vincularse a objetos incrustados
ObjectLas propiedadesList<Object>y no son compatibles con las versiones 10.42.3 y anteriores del SDK de Swift. En las versiones 10.42.4 y posteriores del SDK de Swift, los objetos asimétricos pueden vincularse a objetos no incrustados.EmbeddedObjectyList<EmbeddedObject>son compatibles.
No se puede vincular a un AsymmetricObject desde un Object. Si lo hace, se generará un error.
Los objetos asimétricos no funcionan igual que otros objetos del reino. No se puede:
Agregar un objeto asimétrico a un reino
Eliminar un objeto asimétrico de un reino
Query un objeto asimétrico
Solo puedes crear un objeto asimétrico, que luego se sincroniza unidireccionalmente con la base de datos Atlas vinculada a tu aplicación con Device Sync.
Para obtener más información, consulte: Crear un objeto asimétrico.
Definir datos no estructurados
Nuevo en la versión 10.51.0.
A partir de la versión del SDK,10.51.0 se pueden almacenar colecciones de datos mixtos dentro de una AnyRealmValue propiedad. Esta función permite modelar estructuras de datos complejas, como documentos JSON o MongoDB, sin necesidad de definir un modelo de datos estricto.
Los datos no estructurados son aquellos que no se ajustan fácilmente a un esquema esperado, lo que dificulta o hace poco práctico modelarlos para clases de datos individuales. Por ejemplo, su aplicación podría tener datos muy variables o dinámicos cuya estructura se desconoce en tiempo de ejecución.
Almacenar colecciones en una propiedad mixta ofrece flexibilidad sin sacrificar la funcionalidad, incluyendo una sincronización eficiente al usar Device Sync. Además, puede trabajar con ellas de la misma manera que con una colección no mixta:
Puedes anidar colecciones mixtas hasta 100 niveles.
Puede consultar y reaccionar ante los cambios en colecciones mixtas.
Puede buscar y actualizar elementos de colección mixtos individuales.
Sin embargo, almacenar datos en colecciones mixtas tiene menos rendimiento que usar un esquema estructurado o serializar blobs JSON en una única propiedad de cadena.
Para modelar datos no estructurados en su aplicación, defina las propiedades adecuadas en su esquema como tipos AnyRealmValue. A continuación, puede configurar estas AnyRealmValue propiedades como una lista o un diccionario de AnyRealmValue elementos. Tenga en cuenta que AnyRealmValue no puede representar un MutableSet ni un objeto incrustado.
Tip
Utilice un mapa de tipos de datos mixtos cuando el tipo sea desconocido pero cada valor tendrá un identificador único.
Utilice una lista de tipos de datos mixtos cuando el tipo sea desconocido, pero el orden de los objetos sea importante.