Menu Docs

Página inicial do DocsDesenvolver aplicaçõesAtlas Device SDKs

Tipos suportados - Swift SDK

Nesta página

  • Tipos de coleção
  • Resultados e resultados seccionados
  • Coleções como propriedades
  • As coleções estão ativas
  • Tipos de propriedade suportados
  • Folha de referências de propriedades
  • Definindo valores padrão
  • Identificadores únicos
  • Limitações de tamanho
  • AnyRealmCollection
  • Conjunto mutável
  • Mapa/Dicionário
  • AnyRealmValue
  • Dados geoespaciais
  • Mapear tipos não suportados para tipos suportados
  • Declarar projeções de tipo
  • Em conformidade com o protocolo de projeção de tipo
  • Usar Projeção de Tipo no Modelo

O Realm tem vários tipos para representar grupos de objetos, que chamamos de coleções. Uma coleção é um objeto que contém zero ou mais instâncias de um tipo de Realm. Coleções reais são homogêneas: todos os objetos em uma coleção são do mesmo tipo.

Você pode filtrar e classificar qualquer coleção usando o mecanismo de query do Realm. As coleções estão ativas, então elas sempre refletem o estado atual da instância do reino na thread atual. Você também pode ouvir as alterações na coleção assinando as notificações da coleção.

Todos os tipos de coleção estão em conformidade com o protocolo RealmCollection . Este protocolo herda de CollectionType, para que você possa usar uma coleção Realm como faria com qualquer outra coleção de biblioteca padrão.

Usando o protocolo RealmCollection, você pode escrever código genérico que pode operar em qualquer coleção Realm:

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

Os resultados da coleção Swift SDK é uma classe que representa objetos recuperados de queries. Uma coleção de resultados representa os resultados avaliados displicentemente de uma operação de query. Os resultados são imutáveis: você não pode adicionar ou remover elementos da coleção de resultados. Os resultados têm uma query associada que determina seu conteúdo.

O Swift SDK também fornece SectionedResults, uma coleção segura por tipo que mantém ResultsSection como seus elementos. Cada ResultSection é uma coleção de resultados que contém apenas objetos que pertencem a uma determinada chave de seção.

Por exemplo, um aplicativo que inclui uma lista de contatos pode usar SectionedResults para exibir uma lista de contatos dividida em seções, onde cada seção contém todos os contatos cujo nome começa com a letra fornecida. O ResultsSection cuja chave é "L" conteria "Larry", "Liam" e "Lisa".

Dica

Veja também:

O Swift SDK também oferece vários tipos de coleção que você pode usar como propriedades em seu modelo de dados:

  1. Lista, uma classe que representa relacionamentos entre muitos em modelos.

  2. LinkingObjects, uma classe que representa relacionamentos inversos em modelos.

  3. MutableSet, uma classe que representa um relacionamento para muitos.

  4. Map, uma classe que representa uma array associativa de pares de valores-chave com chaves exclusivas.

  5. AnyRealmCollection, um tipo apagado classe que pode encaminhar chamadas para uma coleção de Realm concreta, como Resultados, Lista ou LinkingObjects.

Como os objetos ativos, as collections do Realm geralmente são ativas:

  • Coleções de resultados em tempo real sempre refletem os resultados atuais da query associada.

  • Listas ativas sempre refletem o estado atual do relacionamento na instância de domínio.

Há dois casos em que uma coleção não está ativa:

  • A coleção não está gerenciada. Por exemplo, uma propriedade List de um Objeto de domínio que ainda não tenha sido adicionado a um domínio ou que tenha sido copiado de um domínio não está ativo.

  • A coleção está congelada.

Combinadas com notificações de coleção, as coleções dinâmicas permitem código limpo e reativo. Por exemplo, suponha que sua visualização exiba os resultados de uma query. Você pode manter uma referência à coleção de resultados em sua classe de exibição e, em seguida, ler a coleção de resultados conforme necessário sem precisar atualizá-la ou validar se ela está atualizada.

Importante

Os índices de resultados podem mudar

Como os resultados se atualizam automaticamente, não armazene o índice posicional de um objeto na coleção ou a contagem de objetos em uma coleção. O índice armazenado ou o valor de contagem podem estar desatualizados no momento em que você o utiliza.

Você pode usar os seguintes tipos para definir as propriedades do modelo de objeto.

Para saber como tipos de dados específicos são mapeados para tipos BSON em um Esquema de Serviços de Aplicativo, consulte Mapeamento de Modelo de Dados na documentação de Serviços de Aplicativo do Atlas.

Veja também Model Data with Device Sync - Swift SDK.

Novidade na versão 10.8.0: tipo UUID

ObjectId é um valor exclusivo de 12 bytes específico do MongoDB. O UUID é um valor global exclusivo de 16 bytes. Você pode indexar os dois tipos e usar qualquer um deles como chave primária.

Observação

Ao declarar valores padrão para atributos de propriedade @Persisted UUID ou ObjectId, ambos estes tipos de sintaxe são válidos:

  • @Persisted var value: UUID

  • @Persisted var value = UUID()

No entanto, o segundo resultará em pior desempenho. Isso ocorre porque o último cria um novo identificador que nunca é usado quando um objeto é lido do Realm, enquanto o primeiro só o cria quando necessário.

@Persisted var id: ObjectId tem comportamento equivalente a @objc dynamic var _id = ObjectId.generate(). Ambos fazem ObjectIds aleatórios.

@Persisted var _id = ObjectId() tem comportamento equivalente a @objc dynamic var _id = ObjectId(). Ambos criam ObjectIds inicializados com zero.

As propriedades de dados e string não podem ter mais de 16MB. Para armazenar quantidades maiores de dados:

  • Divida os dados em pedaços de 16MB, ou

  • Armazene dados diretamente no sistema de arquivos e armazene caminhos para os arquivos no domínio.

O Realm apresenta uma exceção de tempo de execução se o seu aplicativo tentar armazenar mais de 16MB em uma única propriedade.

Para evitar limitações de tamanho e um impacto no desempenho, é melhor não armazenar blobs grandes, como arquivos de imagem e vídeo, diretamente em um território. Em vez disso, salve o arquivo em um armazenamento de arquivos e mantenha apenas o local do arquivo e quaisquer metadados relevantes no domínio.

Para armazenar uma coleção como uma propriedade ou variável sem precisar conhecer o tipo concreto da coleção, o sistema de tipos do Swift requer um wrapper sem tipo, como 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)
}
}

Novidades na versão 10.8.0.

Uma coleção MutableSet representa um relacionamento entre muitos contendo valores distintos. Um MutableSet suporta os seguintes tipos (e suas versões opcionais):

  • Bool

  • Dados

  • Data

  • Decimal128

  • Duplo

  • Flutuador

  • Int

  • Int8

  • Int16

  • Int32

  • Int64

  • Objeto

  • ObjectId

  • String

  • UUID

Como o conjunto de Swift , MutableSet é um tipo genérico que é parametrizado no tipo que armazena. Ao contrário das coleçõesnativas do Swift, Os conjuntos mutáveis de realm são tipos de referência, em oposição aos tipos de valor (structs).

Você só pode chamar os métodos de mutação MutableSets durante uma transação de gravação. Como resultado, o MutableSets é imutável se você abrir o domínio de gerenciamento como um domínio somente para leitura.

Você pode filtrar e classificar um MutableSet com os mesmos predicados de Results. Como outras coleções do Realm, você pode registrar um ouvinte de alterações em um MutableSet.

Por exemplo, um modelo de classe Dog pode conter um MutableSet para citiesVisited:

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

Observação

Ao declarar valores padrão para @Persisted atributos de propriedade MutableSet, ambos estes tipos de sintaxe são válidos:

  • @Persisted var value: MutableSet<String>

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

No entanto, o segundo resultará em um desempenho significativamente pior. Isso ocorre porque o MutableSet é criado quando o objeto pai é criado, em vez de preguiçosamente, conforme necessário.

Novidades na versão 10.8.0.

O Map é uma array associativa que contém pares de valores-chave com chaves exclusivas.

Como o dicionário do Swift , Map é um tipo genérico que é parametrizado em seus tipos de chave e valor. Ao contrário das coleçõesnativas do Swift, Realm Maps são tipos de referência (classes), em oposição aos tipos de valor (structs).

Você pode declarar um Mapa como uma propriedade de um objeto:

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

O Realm não permite o uso de . ou $ caracteres em chaves de mapa. Você pode usar a codificação e a decodificação percentual para armazenar uma chave de mapa que contenha um desses caracteres não permitidos.

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

Observação

Ao declarar valores padrão para atributos de propriedade de mapa do @Persisted, ambos estes tipos de sintaxe são válidos:

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

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

No entanto, o segundo resultará em um desempenho significativamente pior. Isso ocorre porque o Mapa é criado quando o objeto pai é criado, e não de modo displicente conforme necessário.

Novidades na versão 10.8.0.

AnyRealmValue é um tipo de propriedade Realm que pode manter diferentes tipos de dados. Os tipos de dados do AnyRealmValue suportados incluem:

  • Int

  • Flutuador

  • Duplo

  • Decimal128

  • ObjectId

  • UUID

  • Bool

  • Data

  • Dados

  • String

  • Objeto

Este tipo de dados misto é indexável, mas você não pode usá-lo como uma chave primária. Como null é um valor permitido, você não pode declarar um AnyRealmValue como opcional.

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

Novidades na versão 10.47.0.

Os dados geoespaciais, ou "geodados", especificam pontos e objetos geométricos na superfície da Terra.

Se você deseja persistir os dados geoespaciais, eles devem estar em conformidade com a especificação GeoJSON.

Para persistir dados geoespaciais com o Swift SDK, crie uma classe incorporada compatível com GeoJSONV que você pode usar em seu modelo de dados.

O objeto embarcado personalizado deve conter os dois campos exigidos pela especificação GeoJSON:

  • Um campo de propriedade de tipo String que mapeia para uma propriedade type com o valor de "Point": @Persisted var type: String = "Point"

  • Um campo de tipo List<Double> que mapeia para uma propriedade coordinates contendo um par de latitude/longitude: @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])
}
}

Novidades na versão 10.20.0.

Você pode usar a Projeção de Tipo para persistir tipos não suportados como tipos suportados no Realm. Isso permite que você trabalhe com tipos Swift que o Realm não suporta, mas armazene-os como tipos que o Realm suporta. Você pode armazenar uma URL como um String, por exemplo, mas lê-la do Realm e utilizá-la em seu aplicativo como se fosse uma URL.

Para usar a projeção de tipo com o Realm:

  1. Use um dos protocolos de tipo personalizado do Realm para mapear um tipo de dados não suportado para um tipo compatível com o Realm

  2. Use os tipos projetados como propriedades persistentes no modelo de objeto Realm

Você pode mapear um tipo de dados não suportado para um tipo que o Realm suporta utilizando um dos protocolos de projeção do tipo Realm.

O Swift SDK fornece protocolos de projeção de dois tipos:

  • CustomPersistable

  • FailableCustomPersistable

Use CustomPersistable quando não houver chance de a conversão falhar.

Use FailableCustomPersistable quando for possível que a conversão falhe.

// 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 }
}

Dica

Veja também:

Esses são protocolos modelados após o RawRepresentableintegrado da Swift.

O PersistedType pode usar qualquer um dos tipos primitivos suportados pelo Swift SDK. Ele também pode ser um Objeto incorporado.

PersistedType não pode ser opcional ou uma coleção. No entanto, você pode usar o tipo mapeado como uma propriedade opcional ou de coleção em seu modelo de objeto.

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?
}

Um tipo que esteja em conformidade com um dos protocolos de projeção de tipos pode ser usado com a sintaxe de declaração de propriedade @Persisted introduzida no Swift SDK versão 10.10.0. Não funciona com a sintaxe @objc dynamic.

Você pode usar tipos projetados para:

  • Tipos de nível superior

  • Versões opcionais do tipo

  • Os tipos de uma coleção

Ao utilizar um FailableCustomPersistable como uma propriedade, defina-o como uma propriedade opcional. Quando é opcional, o protocolo FailableCustomPersistable mapeia valores inválidos para nil. Quando é uma propriedade obrigatória, ela é desembrulhada à força. Se você tiver um valor que não possa ser convertido para o tipo projetado, a leitura dessa propriedade lançará uma exceção de falha não envolvida.

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
}

Quando o modelo contém tipos projetados, você pode criar o objeto com valores usando o tipo persistente ou atribuindo às propriedades de campo de um objeto inicializado usando os tipos projetados.

// 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)

Quando você declara que seu tipo está em conformidade com um protocolo de projeção de tipo, você especifica o tipo que deve ser mantido no domínio. Por exemplo, se você mapear um tipo personalizado URL para um tipo persistente de String, uma propriedade URL aparecerá como um String no esquema e o acesso dinâmico à propriedade atuará em cadeias de caracteres.

O esquema não representa diretamente os tipos mapeados. Alterar uma propriedade de seu tipo persistente para seu tipo mapeado, ou vice-versa, não exige uma migração.

Captura de tela do Realm Studio mostrando os tipos de campo usando tipos persistentes.
← Relacionamentos de modelo - Swift SDK