Serialização - Kotlin SDK
Nesta página
- Serializadores de tipo de dados Realm
- Registrar um serializador para uma propriedade
- Registrar um serializador para todas as ocorrências em um arquivo
- Vincular automaticamente tipos de Realm a serializadores
- Exemplos de saída de serialização
- Codificação EJSON para Atlas
- Adicionar KSerialization ao seu projeto
- Codificador estável
- Chamar uma função
- Credenciais de função personalizada
- Perfil de usuário e dados personalizados
- Codificador de documento completo
- Importações necessárias
- Definir um serializador
- Aceitação experimental
- Chamar uma função
- Credenciais de função personalizada
- Perfil de usuário e dados personalizados
- Outras bibliotecas de serialização
O Realm Kotlin SDK suporta serialização de Kotlin. Você pode serializar tipos de dados específicos do Realm usando serializadores estáveis ou classes definidas pelo usuário com uma API experimental de serialização de documento completo.
Serializadores de tipo de dados Realm
O Realm Kotlin SDK fornece serializadores para os seguintes tipos de dados para KSerializer:
Tipo de dados Realm | KSerializer para tipo |
---|---|
MutableRealmInt | MutableRealmIntKSerializer::class |
RealmAny | RealmAnyKSerializer::class |
RealmDictionary | RealmDictionaryKSerializer::class |
RealmInstant | RealmInstantKSerializer::class |
RealmList | RealmListKSerializer::class |
RealmSet | RealmSetKSerializer::class |
RealmUUID | RealmUUIDKSerializer::class |
Os serializadores estão localizados em io.realm.kotlin.serializers
.
Para obter exemplos de como o Realm serializa os diferentes tipos de dados, consulte Exemplos de saída de serialização.
A desserialização de tipos de dados de Realm gera instâncias de dados não gerenciadas.
Registrar um serializador para uma propriedade
Você pode registrar um serializador para uma propriedade específica. Use a anotação @Serializable
para vincular-se a um serializador de tipo de dados Realm específico.
class Frog : RealmObject { var name: String = "" var favoritePonds: RealmList<String> = realmListOf() }
Registrar um serializador para todas as ocorrências em um arquivo
Você pode registrar um serializador para todas as ocorrências desse tipo em um arquivo adicionando a declaração ao topo do arquivo:
class) (RealmSetKSerializer::import io.realm.kotlin.ext.realmSetOf import io.realm.kotlin.serializers.RealmSetKSerializer import io.realm.kotlin.types.RealmSet import kotlinx.serialization.UseSerializers
Em seguida, quaisquer objetos que tenham propriedades desse tipo dentro do arquivo podem usar o serializador sem registrá-lo individualmente:
// These objects have RealmSet properties that get serializers // from declaring `@file:UseSerializers(RealmSetKSerializer::class)`. // No need to individually declare them on every `RealmSet` property in the file. class Movie : RealmObject { var movieTitle: String = "" var actors: RealmSet<String> = realmSetOf() } class TVSeries : RealmObject { var seriesTitle: String = "" var episodeTitles: RealmSet<String> = realmSetOf() }
Vincular automaticamente tipos de Realm a serializadores
Para vincular automaticamente todos os tipos de Realm a seus serializadores, você pode adicionar um trecho contendo todos os serializadores ao topo de um arquivo:
( MutableRealmIntKSerializer::class, RealmAnyKSerializer::class, RealmDictionaryKSerializer::class, RealmInstantKSerializer::class, RealmListKSerializer::class, RealmSetKSerializer::class, RealmUUIDKSerializer::class )
Exemplos de saída de serialização
Esses exemplos ilustram como os diferentes tipos de dados do Realm são serializados usando um codificador JSON:
Tipo de dados Realm | Tipo de serialização e exemplo | |||||||
---|---|---|---|---|---|---|---|---|
MutableRealmInt | Serializes using a regular integer value. MutableRealmInt.create(35) serializes to 35 | |||||||
RealmAny | Serializes using a map containing a union of all values and its type. RealmAny.create("hello world") serializes to {"type": "STRING", "string": "hello world"} RealmAny.create(20) serializes to {"type": "INT", "int": 20} | |||||||
Dicionário Realm | Serializes using a generic list. realmDictionaryOf("hello" to "world") serializes to {"hello": "world"} | |||||||
Instante real | Serializes as a BsonDateTime .RealmInstant.now() serializes to {"$date": {"$numberLong": "<millis>"}} | |||||||
Lista de domínios | Serializes using a generic list. realmListOf("hello", world) serializes to ["hello", "world"] | |||||||
RealmSet | Serializes using a generic list. realmSetOf("hello", world) serializes to ["hello", "world"] | |||||||
BsonObjectId ou ObjectId | Serializes as a BsonObjectId .ObjectId.create() serializes to {"$oid": <ObjectId bytes as 24-character, big-endian hex string>} | |||||||
RealmUUID | Serializes as a BsonBinary .RealmUUID.random() serializes to { "$binary": {"base64": "<payload>", "subType": "<t>"}} | |||||||
RealmObject | Serializa usando a configuração polimórfica definida pelo usuário. Faça isso por meio do SerializersModule:
|
Codificação EJSON para Atlas
Novidades na versão 1.9.0.
As API do Realm Kotlin SDK que se comunicam diretamente com o MongoDB Atlas usam a codificação EJSON. O SDK oferece dois tipos de codificadores EJSON:
Um codificador limitado, mas estável
Um codificador experimental que oferece serialização completa de documentos
As API que usam esses codificadores incluem:
Chamadas de funçãodo App Services
Credenciais com autenticação de função personalizada
Perfil de usuário e dados de usuário personalizados
Adicionar KSerialization ao seu projeto
O suporte à serialização EJSON do Realm Kotlin SDK depende da biblioteca oficial de serialização do Kotlin . Você deve adicionar serialização do Kotlin ao seu projeto. Use a mesma versão usada na versão do Realm Kotlin SDK . Consulte a Matriz de compatibilidade de versão no repositório realm-kotlin do GitHub para obter informações sobre as dependências suportadas de cada versão.
A anotação @Serializable
nos exemplos a seguir vem da estrutura de serialização do Kotlin.
Codificador estável
O codificador estável não oferece suporte a classes definidas pelo usuário. Você pode usar esses tipos de argumentos com o codificador estável:
Primitivos
BSON
MutableRealmInt
RealmUUID
ObjectId
RealmInstant
RealmAny
Array
collection
Map
Para retornar uma collection ou mapa, você pode usar BsonArray
ou BsonDocument
.
Chamar uma função
Você pode chamar uma função usando o codificador estável com um tipo de argumento válido e desserializar o resultado.
Neste exemplo, chamamos a função getMailingAddress
com dois argumentos de string e obtemos o resultado como BsonDocument
:
// The `getMailingAddress` function takes a first name and last name and returns an address as a BsonDocument val address = user.functions.call<BsonDocument>("getMailingAddress", "Bob", "Smith") assertEquals(address["street"], BsonString("123 Any Street"))
Credenciais de função personalizada
Você pode criar um Credential
para utilizar com autenticação de função personalizada utilizando o codificador estável como um mapa ou um BsonDocument
:
val credentials = Credentials.customFunction( mapOf( "userId" to 500, "password" to "securePassword" ) ) val bsonCredentials = Credentials.customFunction( BsonDocument( mapOf( "userId" to BsonInt32(500), "password" to BsonString("securePassword") ) ) ) app.login(credentials)
Perfil de usuário e dados personalizados
Você pode acessar um perfil de usuário ou dados de usuário personalizados usando o codificador estável como BsonDocument
:
val user = app.currentUser!! val userProfile = user.profileAsBsonDocument() assertEquals(userProfile["email"], BsonString("my.email@example.com"))
val user = app.currentUser!! val customUserData = user.customDataAsBsonDocument() assertEquals(BsonString("blue"), customUserData?.get("favoriteColor"))
Codificador de documento completo
O codificador de documento completo permite serializar e desserializar classes definidas pelo usuário. Você pode definir e usar KSerializers personalizados para seu tipo com funcionalidades do Atlas que se comunicam diretamente com o MongoDB Atlas usando a codificação EJSON. O codificador de documento completo oferece suporte a serializadores contextuais.
Importante
Isso é experimental
A implementação atual da serialização completa de documento é experimental. Chamar essas APIs quando seu projeto usa uma versão diferente da Serialização de Kotlin da dependência do Realm causa um comportamento indefinido. Consulte a Matriz de compatibilidade de versão no Github repositório do realm-kotlin do para obter informações sobre as dependências suportadas de cada versão.
Importações necessárias
Para usar esse recurso, adicione uma ou mais das seguintes importações ao seu arquivo, conforme relevante:
import kotlinx.serialization.Serializable import io.realm.kotlin.annotations.ExperimentalRealmSerializerApi import org.mongodb.kbson.ExperimentalKBsonSerializerApi import kotlinx.serialization.modules.SerializersModule import io.realm.kotlin.serializers.RealmListKSerializer
Definir um serializador
Ao usar a serialização no Realm Kotlin SDK, você pode definir um serializador de duas maneiras:
Adicione a anotação
@Serializable
a uma classeDefina um KSerializer personalizado para o seu tipo e passe-o para a API relevante
class Person( val firstName: String, val lastName: String )
Você pode definir um serializador EJSON personalizado para seu aplicativo no AppConfiguration
, como no caso em que você deseja utilizar um serializador contexto:
class Frogger( val name: String, val date: LocalDateTime ) AppConfiguration.Builder(FLEXIBLE_APP_ID) .ejson( EJson( serializersModule = SerializersModule { contextual(DateAsIntsSerializer) } ) ) .build()
Aceitação experimental
Como a API de serialização de documentos completa é experimental, você deve adicionar as anotações @OptIn
relevantes para as APIs que você usa.
Chamar uma função
Você pode chamar uma função usando a API experimental com argumentos ou tipos de retorno que usam serializadores personalizados.
Neste exemplo, chamamos a função getMailingAddressForPerson
com um objeto Person
serializado e obtemos o resultado como um objeto Address
desserializado:
class Address( val street: String, val city: String, val state: String, val country: String, val postalCode: String ) class Person( val firstName: String, val lastName: String )
// The `getMailingAddressForPerson` function takes a Person object and returns an Address object using the experimental serializer val address = user.functions.call<Address>("getMailingAddressForPerson"){ add(Person("Bob", "Smith")) } assertEquals(address.street, "123 Any Street")
Dica
As chamadas da Função de Realm para o serializador estável e o serializador de API experimental compartilham o mesmo nome de método. Ao invocar uma função sem parâmetros, você deve fornecer um bloco vazio na instrução para a API experimental.
val color = user.functions.call<PersonalFavorites>("favouriteColor") {}
Credenciais de função personalizada
Você pode definir um serializador personalizado para autenticação de função personalizada usando a API experimental:
class CustomUserCredential( val userId: Int, val password: String )
E use-o ao criar uma credencial de função personalizada:
val credentials = Credentials.customFunction( CustomUserCredential( userId = 500, password = "securePassword" ) ) app.login(credentials)
Perfil de usuário e dados personalizados
Defina um serializador personalizado para perfil de usuário ou dados personalizados:
class UserProfile( val email: String )
class UserCustomData( val favoriteColor: String )
E use o serializador personalizado ao acessar o perfil do usuário ou os dados personalizados do usuário:
val user = app.currentUser!! val userProfile = user.profile<UserProfile>() assertEquals(userProfile.email, "my.email@example.com")
val user = app.currentUser!! val customUserData = user.customData<UserCustomData>() assertEquals("blue", customUserData!!.favoriteColor)
Outras bibliotecas de serialização
Métodos de serialização usados por bibliotecas que dependem de reflexão, como GSON não funcionam com o SDK por padrão.
Isso ocorre porque o plug-in do compilador SDK injeta um campo oculto nos modelos de objetos, prefixado com io_realm_kotlin_
. O SDK usa esse campo oculto para managed o estado do objeto interno. Qualquer biblioteca que dependa de campos em vez de getters e setters precisa ignorar esse campo oculto.
Para usar o SDK com bibliotecas externas, como GSON, exclua os campos ocultos da serialização usando uma correspondência de prefixo:
var gson: Gson = GsonBuilder() .setExclusionStrategies(object: ExclusionStrategy { override fun shouldSkipField(f: FieldAttributes?): Boolean = f?.name?.startsWith("io_realm_kotlin_") ?: false override fun shouldSkipClass(clazz: Class<*>?): Boolean = false }) .create()