Realm Kotlin SDK は Kotlin 直列化をサポートしています。 安定版シリアライザー、または実験的な全ドキュメント直列化 API を使用したユーザー定義のクラスを使用して、特定の Realm データ型を直列化できます。
Realm データ型シリアライザー
Realm Kotlin SDK は、KSerializer に対して次のデータ型のシリアライザーを提供します。
Realm データ型 | KSerializer 型 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
シリアライザーはio.realm.kotlin.serializersにあります。
Realm がさまざまなデータ型を直列化する方法の例については、「 直列化出力の例 」を参照してください。
Realm データ型を逆直列化すると、管理されていないデータ インスタンスが生成されます。
プロパティのシリアライザーを登録する
特定のプロパティのシリアライザーを登録できます。 特定の Realm データ型シリアライザーにバインドするには、 @Serializableアノテーションを使用します。
class Frog : RealmObject { var name: String = "" var favoritePonds: RealmList<String> = realmListOf() }
ファイル内のすべての発生のシリアライザーを登録
ファイルの先頭に宣言を追加することで、ファイル内のその型のすべての出現をシリアライザーを登録できます。
(RealmSetKSerializer::class) import io.realm.kotlin.ext.realmSetOf import io.realm.kotlin.serializers.RealmSetKSerializer import io.realm.kotlin.types.RealmSet import kotlinx.serialization.UseSerializers
次に、ファイル内にその型のプロパティを持つすべてのオブジェクトは、シリアライザーを個別に登録せずにシリアライザーを使用できます。
// 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() }
Realm 型のシリアライザーへの自動バインド
すべての Realm 型をシリアライザーに自動的にバインドするには、すべてのシリアライザーを含む スニペットを ファイルの先頭に追加します。
( MutableRealmIntKSerializer::class, RealmAnyKSerializer::class, RealmDictionaryKSerializer::class, RealmInstantKSerializer::class, RealmListKSerializer::class, RealmSetKSerializer::class, RealmUUIDKSerializer::class )
直列化出力の例
次の例は、JSON エンコードを使用してさまざまな Realm データ型を直列化する方法を示しています。
Realm データ型 | 直列化のタイプと例 | |||||||
|---|---|---|---|---|---|---|---|---|
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} | |||||||
RealmDictionary | Serializes using a generic list. realmDictionaryOf("hello" to "world") serializes to {"hello": "world"} | |||||||
Realmインスタンス | Serializes as a BsonDateTime.RealmInstant.now() serializes to {"$date": {"$numberLong": "<millis>"}} | |||||||
RealmList | 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 または 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 | ユーザーが定義した多形設定を使用して直列化します。 SerializersModule を使用してこれを行います。 |
Atlas の EJSON エンコーディング
バージョン 1.9.0 の新機能。
MongoDB Atlas と直接通信する Realm Kotlin SDK API は、EJSON エンコーディングを使用します。 SDK は 2 種類の EJSON エンコードを提供します。
制限されているが安定したエンコード
完全なドキュメント直列化を提供する実験的なエンコード
これらのエンコードを使用する API には、次のものが含まれます。
App Services関数の呼び出し
ユーザープロファイルとカスタムユーザーデータ
プロジェクトに KSerialization を追加する
Realm Kotlin SDK の EJSON直列化サポートは、公式のKotlin直列化ライブラリに依存します。 Kotlin直列化 をプロジェクトに追加する必要があります。 Realm Kotlin SDKで使用されているのと同じバージョンを使用します。各バージョンでサポートされている依存関係の詳細については、Realm-kotlin GitHubリポジトリの バージョン互換性マトリクス を参照してください。
次の例の@Serializableアノテーションは、 Kotlin 直列化フレームワーク から取得されています。
ステーブル エンコード
Stable エンコードはユーザー定義クラスをサポートしていません。 Stable エンコードでは、次の引数型を使用できます。
プリミティブ
BSON
MutableRealmIntRealmUUIDObjectIdRealmInstantRealmAny配列
コレクション
Map
コレクションまたはマップを返すには、 BsonArrayまたはBsonDocumentを使用します。
関数の呼び出し
有効な引数型を持つ安定版エンコードを使用して関数を呼び出し、結果を逆直列化できます。
この例では、2 つのstring引数を指定して getMailingAddress 関数を呼び出し、結果を 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"))
カスタム関数の認証情報
Stable エンコードをマップまたはBsonDocumentとして使用し、カスタム関数認証で使用するCredentialを作成できます。
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)
ユーザー プロファイルとカスタム データ
安定版エンコードを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"))
フルドキュメントエンコード
フルドキュメント エンコードを使用すると、ユーザー定義クラスを直列化および逆直列化できます。 EJSON エンコーディングを使用して MongoDB Atlas と直接通信する Atlas 機能により、タイプのカスタム KSerializer を定義して使用できます。 フルドキュメント エンコードはコンテキストに応じたシリアライザーをサポートします。
重要
これは実験的なものです
完全なドキュメント直列化の現在の実装は実験的なものです。プロジェクトで Realm の依存関係とは異なるバージョンのKotlinシリアル化を使用している場合にこれらの API を呼び出すと、未定義の動作が発生します。各バージョンでサポートされている依存関係の詳細については、Realm-kotlin Githubリポジトリの バージョン 互換性マトリクス を参照してください。
必要なインポート
この機能を使用するには、関連する場合は次のインポートを 1 つ以上ファイルに追加します。
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
シリアライザーを定義する
Realm Kotlin SDK でシリアル化を使用する場合は、次の 2 つの方法のいずれかでシリアライザーを定義できます。
クラスに
@Serializableアノテーションを追加するタイプに合わせてカスタム KSerializer を定義し、それを関連する API に渡します
class Person( val firstName: String, val lastName: String )
コンテキストに応じたシリアライザーを使用する場合などには、 AppConfigurationでアプリのカスタム EJSON シリアライザーを設定できます。
class Frogger( val name: String, val date: LocalDateTime ) AppConfiguration.Builder(FLEXIBLE_APP_ID) .ejson( EJson( serializersModule = SerializersModule { contextual(DateAsIntsSerializer) } ) ) .build()
試験用オプトイン
全ドキュメント直列化 API は実験的なため、使用する API に関連する@OptInアノテーションを追加する必要があります。
関数の呼び出し
カスタム シリアライザーを使用する引数または戻り値の型を使用して実験的な API を使用して関数を呼び出すことができます。
この例では、シリアル化されたPersonオブジェクトを使用してgetMailingAddressForPerson関数を呼び出し、その結果は逆シリアル化されたAddressオブジェクトとして得られます。
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")
Tip
安定版シリアライザーと実験的な API シリアライザーの Atlas Function 呼び出しは、同じメソッド名を共有します。 パラメーターなしで関数を呼び出す場合は、実験的な API の手順に空のブロックを指定する必要があります。
val color = user.functions.call<PersonalFavorites>("favouriteColor") {}
カスタム関数の認証情報
実験的な API を使用して、カスタム関数認証用のカスタム シリアライザーを定義できます。
class CustomUserCredential( val userId: Int, val password: String )
また、カスタム関数の認証情報を作成するときに使用します。
val credentials = Credentials.customFunction( CustomUserCredential( userId = 500, password = "securePassword" ) ) app.login(credentials)
ユーザー プロファイルとカスタム データ
ユーザープロファイルまたはカスタム データ用にカスタム シリアライザーを定義します。
class UserProfile( val email: String )
class UserCustomData( val favoriteColor: String )
そして、ユーザー プロファイルまたはカスタム ユーザー データにアクセスするときに、カスタム シリアライザーを使用します。
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)
その他の直列化ライブラリ
GSON などのリフレクションに依存するライブラリで使用される直列化メソッドは、デフォルトでは SDK では動作しません 。
これは、SDK コンパイラー プラグインがio_realm_kotlin_のプレフィックスが付いた非表示フィールドをオブジェクトモデルに挿入するためです。 SDK はこの非表示フィールドを使用して内部オブジェクトの状態を管理します。 getter と setter の代わりに フィールドに依存するライブラリは、この非表示フィールドを無視する必要があります。
GSON などの外部ライブラリで SDK を使用するには、プレフィックス一致を使用して非表示フィールドを直列化から除外します。
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()