Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ /

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

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 {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name = ""
@Persisted var breed: String?
@Persisted var dateOfBirth = Date()
}

Observação

Os nomes das classes têm um limite máximo de 57 caracteres UTF-8.

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.

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.

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 individuais

  • Use @objcMembers para declarar uma classe. Em seguida, declare propriedades individuais com dynamic 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.

Você pode declarar propriedades como opcionais ou obrigatórias (não opcionais) usando a sintaxe Swift padrão.

class Person: Object {
// Required string property
@Persisted var name = ""
// Optional string property
@Persisted var address: String?
// Required numeric property
@Persisted var ageYears = 0
// Optional numeric property
@Persisted 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).

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 {
@Persisted(primaryKey: true) var id = 0
@Persisted 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"
}
}

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 {
@Persisted var priceCents = 0
@Persisted(indexed: true) var title = ""
}

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"]
}
}

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
@Persisted var firstName = ""
@Persisted 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"]
}
}

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 {
@Persisted var name: String = ""
@Persisted var owner: String?
// Required enum property
@Persisted var status = TaskStatusEnum.notStarted
// Optional enum property
@Persisted var optionalTaskStatusEnumProperty: TaskStatusEnum?
}

O Realm suporta apenas enums @objc Intapoiados 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?>()
}

Dica

Veja também:

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 {
@Persisted var firstName = ""
@Persisted var lastName = ""
override class public func propertiesMapping() -> [String: String] {
["firstName": "first_name",
"lastName": "last_name"]
}
}

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 Addressopcional 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 {
@Persisted var firstName = ""
@Persisted var lastName = ""
@Persisted var address: Address?
@Persisted var friends = List<Person>()
}
class Address: EmbeddedObject {
@Persisted var city: String = ""
@Persisted var country = ""
}

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> {
@Projected(\Person.firstName) var firstName // Passthrough from original object
@Projected(\Person.address?.city) var homeCity // Rename and access embedded object property through keypath
@Projected(\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 ou EmbeddedObject s como uma collection de valores primitivos

  • Exclusã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.

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 {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var deviceId: String
@Persisted var temperatureInFahrenheit: Float
@Persisted var barometricPressureInHg: Float
@Persisted 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 do List<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 e List<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.

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.

Voltar

Dados do modelo