Definir um Realm Object Model - Swift SDK
Nesta página
- Definir um novo tipo de objeto
- Declarar propriedades
- Atributos de propriedade persistentes
- Atributos de propriedade dinâmica do Objective-C
- Especificar uma propriedade opcional/obrigatória
- Especificar uma chave primária
- Indexe uma propriedade
- Ignorar uma propriedade
- Declarar propriedades enum
- Remapear um nome de propriedade
- Definir uma Projeção de Classe
- Sobre esses exemplos
- Como definir uma projeção de classe
- Definir um objeto assimétrico
- Definir dados não estruturados
Definir um novo tipo de objeto
Você pode definir um Objeto de Realm derivando da classe RLMObject ou RLMEmbeddedObject . O nome da classe se torna o nome da tabela no Realm, e as propriedades da classe persistem no banco de banco de dados. Por isso é mais fácil trabalhar com objetos persistentes do que com objetos regulares do Objective-C.
// 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
Você pode definir um objeto de Realm derivando da classe Objeto ou EmbeddedObject. O nome da classe se torna o nome da tabela no domínio, e as propriedades da classe persistem no banco de dados. Por isso é mais fácil trabalhar com objetos persistentes do que com objetos Swift regulares.
// A dog has an _id primary key, a string name, an optional // string breed, and a date of birth. class Dog: Object { true) var _id: ObjectId (primaryKey: var name = "" var breed: String? var dateOfBirth = Date() }
Observação
Os nomes das classes têm um limite máximo de 57 caracteres UTF-8.
Declarar propriedades
Ao declarar os atributos de propriedade de uma classe, você pode especificar se essas propriedades devem ou não ser gerenciadas pelo domínio. Propriedades gerenciadas são armazenadas ou atualizadas no banco de dados. Propriedades ignoradas não são armazenadas no banco de dados. Você pode misturar propriedades gerenciadas e ignoradas dentro de uma classe.
A sintaxe para marcar propriedades como gerenciadas ou ignoradas varia dependendo da versão do SDK.
Atributos de propriedade persistentes
Novidades na versão 10,10,0: O estilo de declaração @Persisted
substitui as notações de declaração @objc dynamic
, RealmOptional
e RealmProperty
de versões mais antigas do SDK. Para uma versão mais antiga do SDK, consulte: Atributos de propriedade dinâmica Objective-C.
Declare as propriedades do modelo que você deseja armazenar no banco de dados como @Persisted
. Isso permite que elas acessem os dados do banco de dados subjacente.
Quando você declara quaisquer propriedades como @Persisted
dentro de uma classe, as outras propriedades dentro desta classe são automaticamente ignoradas.
Se você misturar as declarações de propriedade @Persisted
e @objc dynamic
dentro de uma definição de classe, todos os atributos de propriedade marcados como @objc dynamic
serão ignorados.
Dica
Veja também:
Nossa página de tipos de propriedades compatíveis contém uma folha de dicas de declaração de propriedade.
Atributos de propriedade dinâmica do Objective-C
Alterado na versão 10,10,0: Esta informação de declaração de propriedade é para versões do SDK anteriores à 10.10.0.
Declare as propriedades do modelo dinâmico do Realm no tempo de execução do Objective-C. Isso permite que elas acessem os dados do banco de dados subjacente.
Você também pode:
Use
@objc dynamic var
para declarar propriedades individuaisUse
@objcMembers
para declarar uma classe. Em seguida, declare propriedades individuais comdynamic var
.
Utilize let
para declarar LinkingObjects
, List
, RealmOptional
e RealmProperty
. O tempo de execução do Objective-C não pode representar estas propriedades genéricas.
Alterado na versão 10,8,0: RealmProperty
substitui RealmOptional
Dica
Veja também:
Nossa página de tipos de propriedades compatíveis contém uma folha de dicas de declaração de propriedade.
Dica
Para obter referência sobre quais tipos o Realm suporta para uso como propriedades, consulte Tipos de propriedades compatíveis.
Ao declarar propriedades não genéricas, use a anotação @Persisted
. O atributo @Persisted
transforma as propriedades do modelo de Realm em acessoras dos dados subjacentes do banco de dados.
Declare propriedades em seu tipo de objeto como faria em uma interface Objective-C normal.
Para usar sua interface em uma array de Realm , passe seu nome de interface para a macro RLM_COLLECTION_TYPE()
. Você pode colocar isso na parte inferior do arquivo de cabeçalho da sua interface. A macro RLM_COLLECTION_TYPE()
cria um protocolo que permite a você marcar RLMArray com seu 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
Ao declarar propriedades não genéricas, use a anotação @objc dynamic
var
. O atributo @objc dynamic var
transforma as propriedades do modelo de Realm em acessoras dos dados subjacentes do banco de dados de dados. Se a classe for declarada como @objcMembers
(Swift 4 ou posterior), você poderá declarar propriedades como dynamic var
sem @objc
.
Para declarar propriedades de tipos genéricos LinkingObjects
, List
e RealmProperty
, use let
. As propriedades genéricas não podem ser representadas no tempo de execução do Objective-C, que o Realm usa para o despacho dinâmico de propriedades dinâmicas.
Observação
Os nomes das propriedades têm um limite máximo de 63 caracteres UTF-8.
Especificar uma propriedade opcional/obrigatória
Você pode declarar propriedades como opcionais ou obrigatórias (não opcionais) usando a sintaxe Swift padrão.
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 uma determinada propriedade como obrigatória , implemente o método requireProperties e retorne uma array de nomes de propriedade obrigatórias.
@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
Alterado na versão 10,8,0: RealmProperty
substitui RealmOptional
Você pode declarar as propriedades String
, Date
, Data
e ObjectId como opcionais ou obrigatórias (não opcionais) usando a sintaxe Swift padrão. Declare tipos numéricos opcionais usando o 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?>() }
O RealmProperty suporta Int
, Float
, Double
, Bool
e todas as versões dimensionadas de Int
(Int8
, Int16
, Int32
, Int64
).
Especificar uma chave primária
Você pode designar uma propriedade como chave primária da sua classe.
As chaves primárias permitem que você localize, atualize e insira objetos de forma eficiente.
As chaves primárias estão sujeitas às seguintes limitações:
Você pode definir apenas uma chave primária por modelo de objeto.
Os valores de chave primária devem ser únicos em todas as instâncias de um objeto em um domínio. O Realm apresenta um erro se você tentar inserir um valor de chave primária duplicado.
Os valores de chave primária são imutáveis. Para alterar o valor da chave primária de um objeto, você deve excluir o objeto original e inserir um novo objeto com um valor de chave primária diferente.
Objetos embarcados não podem definir uma chave primária.
Declare a propriedade com primaryKey: true na notação @Persisted
para definir a chave primária do modelo.
class Project: Object { true) var id = 0 (primaryKey: var name = "" }
Substitua +[RLMObject primaryKey] para definir a chave primária do 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
Substitua Object.primaryKey() para definir a chave primária do 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" } }
Indexe uma propriedade
Você pode criar um índice em uma determinada propriedade do seu modelo. Índices aceleram queries usando operadores de igualdade e IN. Eles tornam a velocidade da operação de inserção e atualização um pouco mais lenta. Os índices usam memória e ocupam mais espaço no arquivo de Realm. Toda entrada do índice tem um mínimo de 12 bytes. É melhor adicionar índices somente ao otimizar o desempenho de leitura para situações específicas.
O Realm permite a indexação para propriedades de string, inteiro, booleano, Date
, UUID
, ObjectId
e AnyRealmValue
.
Novidades na versão 10,8,0: tipos UUID
e AnyRealmValue
Para indexar uma propriedade, declare a propriedade com indexed:true na notação @Persisted
.
class Book: Object { var priceCents = 0 true) var title = "" (indexed: }
Para indexar uma propriedade, substitua +[RLMObject indexedProperties] e retorne uma lista de nomes de propriedade 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 uma propriedade, substitua Object.indexedProperties() e retorne uma lista de nomes de propriedade 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 uma propriedade
Propriedades ignoradas se comportam exatamente como propriedades normais. Elas não podem ser usadas em queries e não acionarão as notificações do Realm . Você ainda pode observá-los usando KVO.
Dica
O Realm ignora automaticamente as propriedades de somente leitura.
Descontinuado desde a versão 10.10.0: ignoredProperties()
Se você não desejar salvar um campo do seu modelo no domínio correspondente, deixe a notação @Persisted
fora do atributo de propriedade.
Adicionalmente, se você misturar as declarações de propriedade @Persisted
e @objc dynamic
dentro de uma classe, as propriedades @objc dynamic
serão ignoradas.
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 = "" }
Se você não deseja salvar um campo em seu modelo para seu Realm, substitua +[RLMObject ignoradoProperties] e retorne uma lista de nomes de propriedade 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
Se você não quiser salvar um campo em seu modelo em seu Realm, substitua Object.ignoredProperties() e retorne uma lista de nomes de propriedade ignorados.
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 propriedades enum
Alterado na versão 10.10.0: O protocolo agora é PersistableEnum
, e não RealmEnum
.
Você pode usar enums com @Persisted
marcando-os como compatíveis com o protocolo PersistableEnum . Um PersistableEnum
pode ser qualquer enumeração do RawRepresentable
cujo tipo bruto seja suportado 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? }
O Realm suporta apenas enums @objc
Int
apoiados por .
// 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?>() }
Remapear um nome de propriedade
Novidades na versão 10.33.0.
Você pode mapear o nome público de uma propriedade em seu modelo de objeto para um nome privado diferente a ser armazenado no Realm. Talvez você queira fazer isso se os nomes das propriedades do esquema do Device Sync usarem letras maiúsculas e minúsculas, por exemplo, enquanto o projeto usa letras maiúsculas e minúsculas do Swift.
Declare o nome que você deseja utilizar em seu projeto como propriedade @Persisted
no modelo de objeto. Em seguida, passe um dicionário contendo os valores públicos e privados para os nomes das propriedades por meio da função propertiesMapping()
.
Neste exemplo, firstName
é o nome de propriedade pública que usamos no código ao longo do projeto para executar operações CRUD. Usando a função propertiesMapping()
, mapeamos isso para armazenar valores usando o nome da propriedade privada first_name
no Realm. Se escrevermos em um realm sincronizado, o esquema Sync verá os valores armazenados usando o nome da propriedade privada first_name
.
class Person: Object { var firstName = "" var lastName = "" override class public func propertiesMapping() -> [String: String] { ["firstName": "first_name", "lastName": "last_name"] } }
Definir uma Projeção de Classe
Sobre esses exemplos
Os exemplos nesta seção usam um conjunto de dados simples. Os dois tipos de objeto de Realm são Person
e um objeto embarcado Address
. Um Person
tem um nome e sobrenome, um Address
opcional e uma lista de amigos que consiste em outros objetos Person
. Um Address
tem uma cidade e um país.
Consulte o esquema para estas duas classes, Person
e Address
, abaixo:
class Person: Object { var firstName = "" var lastName = "" var address: Address? var friends = List<Person>() } class Address: EmbeddedObject { var city: String = "" var country = "" }
Como definir uma projeção de classe
Novidades na versão 10,21,0.
Defina uma projeção de classe criando uma classe do tipo Projeção. Especifique a base Objeto ou Objeto embarcado cujas propriedades você deseja utilizar na projeção de classe. Use o wrapper de propriedade @Projected
para declarar uma propriedade que você deseja projetar a partir de uma propriedade @Persisted
no objeto base.
Observação
Quando você utiliza uma Lista ou um MutableSet em uma projeção de classe, o tipo na projeção de classe deve 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 (\}
Ao definir uma projeção de classe, você pode transformar a propriedade original @Persisted
de várias maneiras:
Passagem: a propriedade tem o mesmo nome e tipo que o objeto original
Renomear: a propriedade tem o mesmo tipo do objeto original, mas outro nome
Resolução de keypath: use a resolução de keypath para acessar as propriedades do objeto original, incluindo propriedades do objeto embarcado
Mapeamento de collections:Listas de projetos ou conjuntos mutáveis de
Object
s ouEmbeddedObject
s como uma collection de valores primitivosExclusão: quando você usa uma projeção de classe, as propriedades subjacentes do objeto de Realm que não são
@Projected
por meio da projeção de classe são excluídas. Isso permite que você observe alterações em uma projeção de classe e não veja alterações em propriedades que não fazem parte da projeção de classe.
Definir um objeto assimétrico
Novidades na versão 10,29,0.
Se o seu aplicativo usa a Flexible Sync, você pode usar o ingestão de dados para sincronizar um objeto unidirecionalmente do seu dispositivo para o banco de dados vinculado ao seu Atlas App Services App. Defina um objeto assimétrico herdando de AsymmetricObject.
class WeatherSensor: AsymmetricObject { true) var _id: ObjectId (primaryKey: var deviceId: String var temperatureInFahrenheit: Float var barometricPressureInHg: Float var windSpeedInMph: Int }
Alterado na versão 10.42.4: Objetos assimétricos podem ser vinculados a objetos não embarcados.
AsymmetricObject
suporta amplamente os mesmos tipos de propriedade do Object
, com algumas exceções:
- Objetos assimétricos só podem vincular a objetos incorporados
Object
e propriedades doList<Object>
não são suportadas nas versões 10.42.3 e anteriores do Swift SDK. Nas versões 10.42.4 e posterior do Swift SDK, objetos assimétricos podem se vincular a objetos não incorporados.EmbeddedObject
eList<EmbeddedObject>
são suportados.
Você não pode criar um link para um AsymmetricObject
de dentro de um Object
. Isso gera um erro.
Objetos assimétricos não funcionam da mesma maneira que outros objetos Realm. Você não pode:
Adicionar um objeto assimétrico a um domínio
Remova um objeto assimétrico de um Realm
Fazer query em um objeto assimétrico
Você só pode criar um objeto Asymmetric, que é sincronizado unidirecionalmente com o banco de dados do Atlas vinculado ao seu aplicativo com o Device Sync.
Para obter mais informações, consulte: Criar um objeto assimétrico.
Definir dados não estruturados
Novidades na versão 10.51.0.
A partir da versão 10.51.0 do SDK, você pode armazenar collections de dados mistos dentro de uma propriedade AnyRealmValue
. Você pode usar esse recurso para modelar estruturas de dados complexas, como documentos JSON ou MongoDB , sem precisar definir um modelo de dados rigoroso.
Dados não estruturados são dados que não estão em conformidade com facilmente um esquema esperado, tornando difícil ou impraticável modelar classes de dados individuais. Por exemplo, seu aplicativo pode ter dados altamente variáveis ou dados dinâmicos cuja estrutura é desconhecida no tempo de execução.
O armazenamento de coleções em uma propriedade mista oferece flexibilidade sem sacrificar a funcionalidade, incluindo sincronização de desempenho ao usar o Device Sync. E você pode trabalhar com eles da mesma forma que faria com uma collection não mista:
Você pode aninhar collections mistas em até 100 níveis.
Você pode consultar e React a alterações em coleções mistas.
Você pode localizar e atualizar elementos individuais de coleção mista.
No entanto, armazenar dados em coleções mistas é menos eficiente do que usar um esquema estruturado ou serializar blobs JSON em uma única propriedade de string.
Para modelar dados não estruturados em seu aplicativo, defina as propriedades apropriadas em seu esquema como tipos AnyRealmValue . Você pode então definir essas propriedades AnyRealmValue
como uma lista ou uma coleção de dicionário de AnyRealmValue
elementos. Observe que AnyRealmValue
não pode representar um MutableSet
ou um objeto incorporado.
Dica
Use um mapa de tipos de dados mistos quando o tipo for desconhecido, mas cada valor terá um identificador exclusivo.
Use uma lista de tipos de dados mistos quando o tipo for desconhecido, mas a ordem dos objetos for significativa.