Define a New Object Type
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 Objeto o ObjetoIntegrado. El nombre de la clase se convierte en el nombre de la tabla en el realm, y las propiedades de la clase se conservan en la base de datos. Esto hace que sea tan fácil trabajar con objetos persistidos como trabajar con objetos regulares de Swift.
// 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
Class names are limited to a maximum of 57 UTF-8 characters.
Declare Properties
When you declare the property attributes of a class, you can specify whether or not those properties should be managed by the realm. Managed properties are stored or updated in the database. Ignored properties are not stored to the database. You can mix managed and ignored properties within a class.
La sintaxis para marcar las propiedades como gestionadas o ignoradas varía según la versión del SDK que utilices.
Persisted Property Attributes
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 model properties that you want to store to the database as @Persisted. This enables them to access the underlying database data.
When you declare any properties as @Persisted within a class, the other properties within that class are automatically ignored.
If you mix @Persisted and @objc dynamic property declarations within a class definition, any property attributes marked as @objc dynamic will be ignored.
Tip
Nuestra página de Tipos de propiedad admitidos contiene una chuleta de declaración de propiedad.
Objective-C Dynamic Property Attributes
Cambiado en la versión 10.10.0: Esta información de declaración de propiedad es para versiones del SDK anteriores a la 10.10.0.
Declara propiedades dinámicas del modelo Realm en el tiempo de ejecución de Objective-C. Esto les permite acceder a los datos subyacentes de la base de datos.
Puedes:
Utiliza
@objc dynamic varpara declarar propiedades individualesUtilice
@objcMemberspara declarar una clase. Luego, declare las propiedades individuales condynamic var.
Use let to declare LinkingObjects, List, RealmOptional and RealmProperty. The Objective-C runtime cannot represent these generic properties.
Changed in version 10.8.0: RealmProperty replaces RealmOptional
Tip
Nuestra página de Tipos de propiedad admitidos contiene una chuleta de declaración de propiedad.
Tip
For reference on which types Realm supports for use as properties, see Supported Property Types.
When declaring non-generic properties, use the @Persisted annotation. The @Persisted attribute turns Realm model properties into accessors for the underlying database data.
Declare las propiedades en su tipo de objeto Realm 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.
To declare properties of generic types LinkingObjects, List, and RealmProperty, use let. Generic properties cannot be represented in the Objective‑C runtime, which Realm uses for dynamic dispatch of dynamic properties.
Nota
Los nombres de las propiedades están limitados a un máximo de 63 caracteres UTF-8.
Specify an Optional/Required Property
You can declare properties as optional or required (non-optional) using standard Swift syntax.
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? }
To declare a given property as required, implement the requiredProperties method and return an array of required property names.
@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
Changed in version 10.8.0: RealmProperty replaces 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 supports Int, Float, Double, Bool, and all of the sized versions of Int (Int8, Int16, Int32, Int64).
Specify a Primary Key
Puede designar una propiedad como la llave primaria de su clase.
Primary keys allow you to efficiently find, update, and upsert objects.
Primary keys are subject to the following limitations:
You can define only one primary key per object model.
Primary key values must be unique across all instances of an object in a realm. Realm throws an error if you try to insert a duplicate primary key value.
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 the property with primaryKey: true on the @Persisted notation to set the model's primary key.
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
Override Object.primaryKey() to set the model's primary key.
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 en situaciones específicas.
Realm supports indexing for string, integer, boolean, Date, UUID, ObjectId, and AnyRealmValue properties.
New in version 10.8.0: UUID and AnyRealmValue types
To index a property, declare the property with indexed:true on the @Persisted notation.
class Book: Object { var priceCents = 0 (indexed: true) var title = "" }
Para indexar una propiedad, sobreescribe +[RLMObject indexedProperties] y devuelve 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
To index a property, override Object.indexedProperties() and return a list of indexed property names.
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.
Deprecated since version 10.10.0: ignoredProperties()
If you don't want to save a field in your model to its realm, leave the @Persisted notation off the property attribute.
Additionally, if you mix @Persisted and @objc dynamic property declarations within a class, the @objc dynamic properties will be ignored.
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 = "" }
If you don't want to save a field in your model to its realm, override +[RLMObject ignoredProperties] and return a list of ignored property names.
@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
Changed in version 10.10.0: Protocol is now PersistableEnum rather than RealmEnum.
You can use enums with @Persisted by marking them as complying with the PersistableEnum protocol. A PersistableEnum can be any RawRepresentable enum whose raw type is a type that Realm supports.
// 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 supports only Int-backed @objc enums.
// 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
Remap a Property Name
New in version 10.33.0.
You can map the public name of a property in your object model to a different private name to store in the realm. You might want to do this if your Device Sync schema property names use snake case, for example, while your project uses Swift-idiomatic camel case.
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().
In this example, firstName is the public property name we use in the code throughout the project to perform CRUD operations. Using the propertiesMapping() function, we map that to store values using the private property name first_name in the realm. If we write to a synced realm, the Sync schema sees the values stored using the private property name first_name.
class Person: Object { var firstName = "" var lastName = "" override class public func propertiesMapping() -> [String: String] { ["firstName": "first_name", "lastName": "last_name"] } }
Define a Class Projection
Acerca de estos ejemplos
The examples in this section use a simple data set. The two Realm object types are Person and an embedded object Address. A Person has a first and last name, an optional Address, and a list of friends consisting of other Person objects. An Address has a city and country.
See the schema for these two classes, Person and Address, below:
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
New in version 10.21.0.
Define a class projection by creating a class of type Projection. Specify the Object or EmbeddedObject base whose properties you want to use in the class projection. Use the @Projected property wrapper to declare a property that you want to project from a @Persisted property on the base object.
Nota
Cuando se usa un List 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 }
When you define a class projection, you can transform the original @Persisted property in several ways:
Passthrough: la propiedad tiene el mismo nombre y tipo que el objeto original
Rename: the property has the same type as the original object, but a different name
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 colección: el proyecto lista 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
New in version 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 versión 10.42.4: Los objetos asimétricos pueden vincularse a objetos no incrustados.
AsymmetricObject broadly supports the same property types as Object, with a few exceptions:
- Los objetos asimétricos solo pueden vincularse a objetos incrustados.
ObjectandList<Object>properties are not supported in Swift SDK versions 10.42.3 and earlier. In Swift SDK versions 10.42.4 and later, asymmetric objects can link to non-embedded objects.EmbeddedObjectandList<EmbeddedObject>are supported.
You cannot link to an AsymmetricObject from within an Object. Doing so throws an error.
Asymmetric objects do not function in the same way as other Realm Objects. You cannot:
Add an asymmetric object to a realm
Remove an asymmetric object from a realm
Query un objeto asimétrico
You can only create an Asymmetric object, which then syncs unidirectionally to the Atlas database linked to your App with Device Sync.
For more information, see: Create an Asymmetric Object.
Define Unstructured Data
Nuevo en la versión 10.51.0.
Starting in SDK version 10.51.0, you can store collections of mixed data within a AnyRealmValue property. You can use this feature to model complex data structures, such as JSON or MongoDB documents, without having to define a strict data model.
Unstructured data is data that doesn't easily conform to an expected schema, making it difficult or impractical to model to individual data classes. For example, your app might have highly variable data or dynamic data whose structure is unknown at runtime.
Storing collections in a mixed property offers flexibility without sacrificing functionality, including performant synchronization when using Device Sync. And you can work with them the same way you would a non-mixed collection:
Se pueden anidar colecciones mixtas hasta 100 niveles.
You can query on and react to changes on mixed collections.
You can find and update individual mixed collection elements.
However, storing data in mixed collections is less performant than using a structured schema or serializing JSON blobs into a single string property.
To model unstructured data in your app, define the appropriate properties in your schema as AnyRealmValue types. You can then set these AnyRealmValue properties as a list or a dictionary collection of AnyRealmValue elements. Note that AnyRealmValue cannot represent a MutableSet or an embedded object.
Tip
Use a map of mixed data types when the type is unknown but each value will have a unique identifier.
Utilice una lista de tipos de datos mixtos cuando el tipo sea desconocido, pero el orden de los objetos sea importante.