Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Datos del modelo

Tipos admitidos - Swift SDK

Realm has several types to represent groups of objects, which we call collections. A collection is an object that contains zero or more instances of one Realm type. Realm collections are homogenous: all objects in a collection are of the same type.

You can filter and sort any collection using Realm's query engine. Collections are live, so they always reflect the current state of the realm instance on the current thread. You can also listen for changes in the collection by subscribing to collection notifications.

Todos los tipos de colección cumplen con las ProtocoloRealmCollection. Este protocolo hereda de CollectionType., por lo que puedes usar una colección de Realm como lo harías con cualquier otra colección de biblioteca estándar.

Using the RealmCollection protocol, you can write generic code that can operate on any Realm collection:

func operateOn<C: RealmCollection>(collection: C) {
// Collection could be either Results or List
print("operating on collection containing \(collection.count) objects")
}

The Swift SDK Results collection is a class representing objects retrieved from queries. A Results collection represents the lazily-evaluated results of a query operation. Results are immutable: you cannot add or remove elements to or from the results collection. Results have an associated query that determines their contents.

El Swift SDK también proporciona SectionedResults, una colección de tipos seguros que contiene ResultsSection como sus elementos. Cada ResultSection es una colección de resultados que contiene únicamente objetos que pertenecen a una clave de sección determinada.

For example, an app that includes a contact list might use SectionedResults to display a list of contacts divided into sections, where each section contains all the contacts whose first name starts with the given letter. The ResultsSection whose key is "L" would contain "Larry", "Liam", and "Lisa".

Tip

El SDK de Swift también ofrece varios tipos de colección que puedes utilizar como propiedades en tu modelo de datos:

  1. Lista, una clase que representa relaciones de muchos en los modelos.

  2. LinkingObjects, una clase que representa relaciones inversas en los modelos.

  3. MutableSet, una clase que representa una relación de múltiples.

  4. Mapa, una clase que representa una matriz asociativa de pares clave-valor con claves únicas.

  5. AnyRealmCollection, a type-erased class that can forward calls to a concrete Realm collection like Results, List or LinkingObjects.

Like live objects, Realm collections are usually live:

  • Live results collections always reflect the current results of the associated query.

  • Live lists always reflect the current state of the relationship on the realm instance.

There are two cases when a collection is not live:

  • The collection is unmanaged. For example, a List property of a Realm object that has not been added to a realm yet or that has been copied from a realm is not live.

  • The collection is frozen.

Combined with collection notifications, live collections enable clean, reactive code. For example, suppose your view displays the results of a query. You can keep a reference to the results collection in your view class, then read the results collection as needed without having to refresh it or validate that it is up-to-date.

Importante

Results indexes may change

Dado que los resultados se actualizan automáticamente, no se debe almacenar el índice posicional de un objeto en la colección ni la cuenta de objetos en una colección. El índice almacenado o el valor de la cuenta podría estar desactualizado para cuando lo utilices.

You can use the following types to define your object model properties.

Para aprender cómo se asignan tipos de datos específicos a los BSON types en un esquema de App Services, consulta Mapeo del modelo de datos en la documentación de Atlas App Services.

Consulta también Modelar datos con Device Sync - Swift SDK.

Changed in version 10.10.0: @Persisted property declaration syntax

Tipo
Requerido
Opcional

Booleano

@Persisted var boolName: Bool
@Persisted var optBoolName: Bool?

Int, Int8, Int16, Int32, Int64

@Persisted var intName: Int
@Persisted var optIntName: Int?

Float

@Persisted var floatName: Float
@Persisted var optFloatName: Float?

Double

@Persisted var doubleName: Double
@Persisted var optDoubleName: Double?

String

@Persisted var stringName: String
@Persisted var optStringName: String?

Datos

@Persisted var dataName: Data
@Persisted var optDataName: Data?

fecha

@Persisted var dateName: Date
@Persisted var optDateName: Date?

Decimal128

@Persisted var decimalName: Decimal128
@Persisted var optDecimalName: Decimal128?
@Persisted var uuidName: UUID
@Persisted var optUuidName: UUID?
@Persisted var objectIdName: ObjectId
@Persisted var optObjectIdName: ObjectId?
@Persisted var listName: List<MyCustomObjectType>

N/A

@Persisted var mutableSetName: MutableSet<String>

N/A

@Persisted var mapName: Map<String, String>

N/A

@Persisted var anyRealmValueName: AnyRealmValue

N/A

Objetodefinido por el usuario

N/A

@Persisted var optObjectPropertyName: MyCustomObjectType?

Definido por el usuario EmbeddedObject

N/A

@Persisted var optEmbeddedObjectPropertyName: MyEmbeddedObjectType?

Definidos por el usuario Enumeraciones

@Persisted var enumName: MyPersistableEnum
@Persisted var optEnumName: MyPersistableEnum?

CGFloat se desaconsejan las propiedades, ya que el tipo no es independiente de la plataforma.

To use Key-Value Coding with a user-defined object in the @Persisted syntax, add the @objc attribute: @Persisted @objc var myObject: MyClass?

With the @Persisted property declaration syntax, you may see a performance impact when setting default values for:

  • List

  • MutableSet

  • Dictionary

  • Decimal128

  • UUID

  • ObjectId

@Persisted var listProperty: List<Int> and @Persisted var listProperty = List<Int>() are both valid, and are functionally equivalent. However, the second declaration will result in poorer performance.

Esto se debe a que la Lista se crea cuando se crea el objeto principal, en lugar de hacerlo de manera perezosa según sea necesario. Para la mayoría de los tipos, esta es una diferencia tan pequeña que no se puede medir. Para los tipos listados aquí, puedes ver un impacto en el rendimiento al usar el segundo estilo de declaración.

Tipo
Requerido
Opcional

Booleano

@property BOOL boolName;
@property NSNumber<RLMBool> *optBoolName;

entero

@property int intName;
@property NSNumber<RLMInt> *optIntName;

Float

@property float floatName;
@property NSNumber<RLMFloat> *optFloatName;

Double

@property double doubleName;
@property NSNumber<RLMDouble> *optDoubleName;

String

@property NSString *stringName;
@property NSString *optStringName;

Datos

@property NSData *dataName;
@property NSData *optDataName;

fecha

@property NSDate *dateName;
@property NSDate *optDateName;

Decimal128

@property RLMDecimal128 *decimalName;
@property RLMDecimal128 *optDecimalName;

NSUUID

@property NSUUID *uuidName;
@property NSUUID *optUuidName;
@property RLMObjectId *objectIdName;
@property RLMObjectId *optObjectIdName;
@property RLMArray<MyObject *><MyObject> *arrayName;

N/A

@property RLMSet<RLMString> *setName;

N/A

@property RLMDictionary<NSString *, NSString *><RLMString, RLMString> *dictionaryName;

N/A

RLMObjectdefinido por el usuario

N/A

@property MyObject *optObjectPropertyName;

RLMEmbeddedObjectdefinido por el usuario

N/A

@property MyEmbeddedObject *optEmbeddedObjectPropertyName;

Además:

  • Integral types int, NSInteger, long, long long

CGFloat se desaconsejan las propiedades, ya que el tipo no es independiente de la plataforma.

Changed in version 10.8.0: RealmProperty replaces RealmOptional

Tipo
Requerido
Opcional

Booleano

@objc dynamic var value = false
let value = RealmProperty<Bool?>()

Int, Int8, Int16, Int32, Int64

@objc dynamic var value = 0
let value = RealmProperty<Int?>()

Float

@objc dynamic var value: Float = 0.0
let value = RealmProperty<Float?>()

Double

@objc dynamic var value: Double = 0.0
let value = RealmProperty<Double?>()

String

@objc dynamic var value = ""
@objc dynamic var value: String? = nil

Datos

@objc dynamic var value = Data()
@objc dynamic var value: Data? = nil

fecha

@objc dynamic var value = Date()
@objc dynamic var value: Date? = nil

Decimal128

@objc dynamic var decimal: Decimal128 = 0
@objc dynamic var decimal: Decimal128?
@objc dynamic var uuid = UUID()
@objc dynamic var uuidOpt: UUID?
@objc dynamic var objectId = ObjectId.generate()
@objc dynamic var objectId: ObjectId?
let value = List<Type>()
let value = MutableSet<Type>()
let value = Map<String, String>()
let value = RealmProperty<AnyRealmValue>()

N/A

Objetodefinido por el usuario

N/A

@objc dynamic var value: MyClass?

Además:

Puedes usar RealmProperty <T?> para representar enteros, dobles y otros tipos como opcionales.

CGFloat se desaconsejan las propiedades, ya que el tipo no es independiente de la plataforma.

New in version 10.8.0: UUID type

ObjectId es un valor único de 12 bytes específico de MongoDB. UUID es un valor único a nivel mundial de 16 bytes. Puede indexar ambos tipos y utilizar cualquiera de ellos como llave primaria.

Nota

When declaring default values for @Persisted UUID or ObjectId property attributes, both of these syntax types are valid:

  • @Persisted var value: UUID

  • @Persisted var value = UUID()

Sin embargo, la segunda tendrá un rendimiento inferior. Esto se debe a que la última crea un nuevo identificador que nunca se utiliza cuando se lee un objeto de la realm, mientras que la primera solo los crea cuando es necesario.

@Persisted var id: ObjectId has equivalent behavior to @objc dynamic var _id = ObjectId.generate(). They both make random ObjectIds.

@Persisted var _id = ObjectId() has equivalent behavior to @objc dynamic var _id = ObjectId(). They both make zero-initialized ObjectIds.

Data and string properties cannot hold more than 16MB. To store larger amounts of data, either:

  • Break the data into 16MB chunks, or

  • Almacene datos directamente en el sistema de archivos y almacene rutas a los archivos en el realm.

Realm throws a runtime exception if your app attempts to store more than 16MB in a single property.

Para evitar limitaciones de tamaño e impacto en el rendimiento, lo mejor es no almacenar blobs grandes, como archivos de imágenes y videos, directamente en un realm. En cambio, guarda el archivo en un almacén de archivos y mantén solo la ubicación del archivo y cualquier metadato relevante en el realm.

To store a collection as a property or variable without needing to know the concrete collection type, Swift's type system requires a type-erased wrapper like AnyRealmCollection:

class ViewController {
// let collection: RealmCollection
// ^
// error: protocol 'RealmCollection' can only be used
// as a generic constraint because it has Self or
// associated type requirements
//
// init<C: RealmCollection>(collection: C) where C.ElementType == MyModel {
// self.collection = collection
// }
let collection: AnyRealmCollection<MyModel>
init<C: RealmCollection & _ObjcBridgeable>(collection: C) where C.ElementType == MyModel {
self.collection = AnyRealmCollection(collection)
}
}

New in version 10.8.0.

Una colección MutableSet representa una relación de varios valores que contiene valores distintos. Un MutableSet admite los siguientes tipos (y sus versiones opcionales):

  • Booleano

  • Datos

  • fecha

  • Decimal128

  • Double

  • Float

  • Int

  • Int8

  • Int16

  • Int32

  • Int64

  • Objeto

  • ObjectId

  • String

  • UUID

Like Swift's Set, MutableSet is a generic type that is parameterized on the type it stores. Unlike native Swift collections, Realm mutable sets are reference types, as opposed to value types (structs).

You can only call the MutableSets mutation methods during a write transaction. As a result, MutableSets are immutable if you open the managing realm as a read-only realm.

You can filter and sort a MutableSet with the same predicates as Results. Like other Realm collections, you can register a change listener on a MutableSet.

Por ejemplo, un modelo de clase Dog podría contener un MutableSet para citiesVisited:

class Dog: Object {
@Persisted var name = ""
@Persisted var currentCity = ""
@Persisted var citiesVisited: MutableSet<String>
}

Nota

When declaring default values for @Persisted MutableSet property attributes, both of these syntax types is valid:

  • @Persisted var value: MutableSet<String>

  • @Persisted var value = MutableSet<String>()

Sin embargo, la segunda opción resultará en un rendimiento significativamente peor. Esto se debe a que MutableSet se crea cuando se crea el objeto parent, en lugar de crearse de manera diferida según sea necesario.

New in version 10.8.0.

The Map is an associative array that contains key-value pairs with unique keys.

Like Swift's Dictionary, Map is a generic type that is parameterized on its key and value types. Unlike native Swift collections, Realm Maps are reference types (classes), as opposed to value types (structs).

You can declare a Map as a property of an object:

class Dog: Object {
@Persisted var name = ""
@Persisted var currentCity = ""
// Map of city name -> favorite park in that city
@Persisted var favoriteParksByCity: Map<String, String>
}

Realm disallows the use of . or $ characters in map keys. You can use percent encoding and decoding to store a map key that contains one of these disallowed characters.

// Percent encode . or $ characters to use them in map keys
let mapKey = "New York.Brooklyn"
let encodedMapKey = "New York%2EBrooklyn"

Nota

When declaring default values for @Persisted Map property attributes, both of these syntax types is valid:

  • @Persisted var value: Map<String, String>

  • @Persisted var value = Map<String, String>()

However, the second will result in significantly worse performance. This is because the Map is created when the parent object is created, rather than lazily as needed.

Changed in version 10.51.0: AnyRealmValue properties can hold lists or maps of mixed data.

New in version 10.8.0.

AnyRealmValue is a Realm property type that can hold different data types. Supported AnyRealmValue data types include:

  • Int

  • Float

  • Double

  • Decimal128

  • ObjectID

  • UUID

  • Booleano

  • fecha

  • Datos

  • String

  • Lista

  • Map

  • Objeto

AnyRealmValue no puede contener un MutableSet u objeto incrustado.

Este tipo de dato mixto es indexable, pero no se puede usar como clave principal. Dado null que es un valor permitido, no se puede declarar un AnyRealmValue como opcional.

class Dog: Object {
@Persisted var name = ""
@Persisted var currentCity = ""
@Persisted var companion: AnyRealmValue
}

En la versión 10.51.0 y posteriores, un tipo de dato AnyRealmValue puede contener colecciones (una lista o mapa, pero no un conjunto) de elementos AnyRealmValue. Puede utilizar colecciones mixtas para modelar datos no estructurados o variables. Para obtener más información, consulte Definir datos no estructurados.

  • Se pueden anidar colecciones mixtas hasta 100 niveles.

  • You can query mixed collection properties and register a listener for changes, as you would a normal collection.

  • You can find and update individual mixed collection elements

  • You cannot store sets or embedded objects in mixed collections.

Para usar colecciones mixtas en tu aplicación, define la propiedad de tipo AnyRealmValue en tu modelo de datos. Después, puedes crear las colecciones de lista o mapa como cualquier otro valor de datos mixtos.

New in version 10.47.0.

Geospatial data, or "geodata", specifies points and geometric objects on the Earth's surface.

Si deseas almacenar datos geoespaciales, estos deben ajustarse a la especificación GeoJSON.

To persist geospatial data with the Swift SDK, create a GeoJSON-compatible embedded class that you can use in your data model.

Your custom embedded object must contain the two fields required by the GeoJSON spec:

  • Un campo de tipo String propiedad que se asigna a una propiedad type con el valor de "Point": @Persisted var type: String = "Point"

  • A field of type List<Double> that maps to a coordinates property containing a latitude/longitude pair: @Persisted private var coordinates: List<Double>

class CustomGeoPoint: EmbeddedObject {
@Persisted private var type: String = "Point"
@Persisted private var coordinates: List<Double>
public var latitude: Double { return coordinates[1] }
public var longitude: Double { return coordinates[0] }
convenience init(_ latitude: Double, _ longitude: Double) {
self.init()
// Longitude comes first in the coordinates array of a GeoJson document
coordinates.append(objectsIn: [longitude, latitude])
}
}

New in version 10.20.0.

Puedes usar Proyección de tipo para guardar tipos no soportados como tipos soportados en Realm. Esto te permite trabajar con tipos de Swift que no están soportados por Realm, pero almacenarlos como tipos que sí están soportados por Realm. Por ejemplo, puedes almacenar una URL como un String, pero leerla desde Realm y utilizarla en tu aplicación como si fuese una URL.

To use type projection with Realm:

  1. Use one of Realm's custom type protocols to map an unsupported data type to a type that Realm supports

  2. Use los tipos proyectados como propiedades @Persisted en el modelo de objetos Realm

You can map an unsupported data type to a type that Realm supports using one of the Realm type projection protocols.

El SDK de Swift proporciona dos protocolos de proyección de tipos:

  • CustomPersistable

  • FailableCustomPersistable

Utiliza CustomPersistable cuando no haya posibilidad de que la conversión falle.

Utiliza FailableCustomPersistable cuando sea posible que la conversión falle.

// Extend a type as a CustomPersistable if if is impossible for
// conversion between the mapped type and the persisted type to fail.
extension CLLocationCoordinate2D: CustomPersistable {
// Define the storage object that is persisted to the database.
// The `PersistedType` must be a type that Realm supports.
// In this example, the PersistedType is an embedded object.
public typealias PersistedType = Location
// Construct an instance of the mapped type from the persisted type.
// When reading from the database, this converts the persisted type to the mapped type.
public init(persistedValue: PersistedType) {
self.init(latitude: persistedValue.latitude, longitude: persistedValue.longitude)
}
// Construct an instance of the persisted type from the mapped type.
// When writing to the database, this converts the mapped type to a persistable type.
public var persistableValue: PersistedType {
Location(value: [self.latitude, self.longitude])
}
}
// Extend a type as a FailableCustomPersistable if it is possible for
// conversion between the mapped type and the persisted type to fail.
// This returns nil on read if the underlying column contains nil or
// something that can't be converted to the specified type.
extension URL: FailableCustomPersistable {
// Define the storage object that is persisted to the database.
// The `PersistedType` must be a type that Realm supports.
public typealias PersistedType = String
// Construct an instance of the mapped type from the persisted type.
// When reading from the database, this converts the persisted type to the mapped type.
// This must be a failable initilizer when the conversion may fail.
public init?(persistedValue: String) { self.init(string: persistedValue) }
// Construct an instance of the persisted type from the mapped type.
// When writing to the database, this converts the mapped type to a persistable type.
public var persistableValue: String { self.absoluteString }
}

Tip

These are protocols modeled after Swift's built-in RawRepresentable.

El PersistedType puede usar cualquiera de los tipos primitivos compatibles con el SDK de Swift. También puede ser un objeto incrustado.

PersistedType cannot be an optional or a collection. However you can use the mapped type as an optional or collection property in your object model.

extension URL: FailableCustomPersistable {
// The `PersistedType` cannot be an optional, so this is not a valid
// conformance to the FailableCustomPersistable protocol.
public typealias PersistedType = String?
...
}
class Club: Object {
@Persisted var id: ObjectId
@Persisted var name: String
// Although the `PersistedType` cannot be optional, you can use the
// custom-mapped type as an optional in your object model.
@Persisted var url: URL?
}

Un tipo que cumpla con uno de los protocolos de proyección de tipos puede utilizarse con la sintaxis de declaración de propiedades @Persisted introducida en la versión 10.10.0 del SDK de Swift. No funciona con la sintaxis @objc dynamic.

You can use projected types for:

  • Top-level types

  • versiones opcionales del tipo

  • The types for a collection

When using a FailableCustomPersistable as a property, define it as an optional property. When it is optional, the FailableCustomPersistable protocol maps invalid values to nil. When it is a required property, it is force-unwrapped. If you have a value that can't be converted to the projected type, reading that property throws an unwrapped fail exception.

class Club: Object {
@Persisted var id: ObjectId
@Persisted var name: String
// Since we declared the URL as a FailableCustomPersistable,
// it must be optional.
@Persisted var url: URL?
// Here, the `location` property maps to an embedded object.
// We can declare the property as required.
// If the underlying field contains nil, this becomes
// a default-constructed instance of CLLocationCoordinate
// with field values of `0`.
@Persisted var location: CLLocationCoordinate2D
}
public class Location: EmbeddedObject {
@Persisted var latitude: Double
@Persisted var longitude: Double
}

When your model contains projected types, you can create the object with values using the persisted type, or by assigning to the field properties of an initialized object using the projected types.

// Initialize objects and assign values
let club = Club(value: ["name": "American Kennel Club", "url": "https://akc.org"])
let club2 = Club()
club2.name = "Continental Kennel Club"
// When assigning the value to a type-projected property, type safety
// checks for the mapped type - not the persisted type.
club2.url = URL(string: "https://ckcusa.com/")!
club2.location = CLLocationCoordinate2D(latitude: 40.7509, longitude: 73.9777)

Cuando declara su tipo como conforme a un protocolo de proyección de tipos, especifica el tipo que debe persistirse en realm. Por ejemplo, si asigna un tipo personalizado URL a un tipo persistido de String, una propiedad URL aparece como un String en el esquema, y el acceso dinámico a la propiedad actúa sobre cadenas.

The schema does not directly represent mapped types. Changing a property from its persisted type to its mapped type, or vice versa, does not require a migration.

Realm Studio screenshot showing the field types using persisted types.

Volver

Relaciones