Takuji->find;

株式会社はてなでアプリケーションエンジニアやってます、技術的な記事を書いているつもり

RealmをKotlinで使う時に役立つtips - Realm Advent Calendar 2015

こんにちは、RealmとKotlinが大好きなtakuji31です。

これはRealm Advent Calendar 2015、9日目の記事です。

qiita.com

8日目はNikoYuwonoさんの「DynamicRealmを使って、Realm Browserを作ってみましょう!」でした。

qiita.com

さて、本日はRealmをKotlinで使う時に役立つを紹介したいと思います。

Realm + Kotlin = Love

constructor + default value

Kotlinはコンストラクター内でpropertyを定義することができます。

コンストラクターでひたすらpropertyを定義しておくと、オブジェクト生成時にpropertyに値を勝手に代入してくれてとても便利ですね。

ですが、RealmObjectのサブクラスには引数なしのデフォルトコンストラクターが必須になります。

そこで、コンストラクターのpropertyにデフォルト値を設定してやることで、Kotlinがデフォルトコンストラクターを生成してくれます。

これでデフォルトコンストラクターが生成されつつ、unmanagedなオブジェクトを新規作成する時に値を代入することができますね。

open class User(
        @PrimaryKey open var uuid: String = UUID.randomUUID().toString(),
        open var name: String? = null,
) : RealmObject() {}

Extension property

KotlinのpropertyはJavaのfield+setter/getter定義と違い、定義する時も使う時も"propertyっぽく"使えます。

しかし、内部的にはJavaのそれと同じ仕組みになっているので、Realmに保存できないような値を変換するpropertyを定義したい時に、RealmObjectの制限である"保存しないプロパティに@Ignoreを設定する"に引っかかります。

もちろんfieldに@Ignoreを指定すればいいのですが、

@field:io.realm.annotations.Ignore

なんて指定を毎回するのは面倒だと思います、更に使いもしないfieldがオブジェクト内に用意されてしまうのはちょっと気持ち悪いですね。

そこで、Extension propertyの出番です。Extension propertyはJava的にはUtilクラスのような実装になるので、@Ignoreをつける必要がありませんし、無駄なfieldも定義されませんしとても良さげです。

以下のコードはThreeTen Android BackportのInstantオブジェクトをDateオブジェクトとして保存するコードです。

open class User(
        @PrimaryKey open var uuid: String = UUID.randomUUID().toString(),
        open var name: String? = null,
        open var createdDate : Date = Date()
) : RealmObject() {

}

var User.createdAt : Instant
    get() = DateTimeUtils.toInstant(createdDate)
    set(value) {
        createdDate = DateTimeUtils.toDate(value)
    }

fieldが生成されないので、オブジェクト内に値をキャッシュしたいような時には使えないかもしれません。

また、createdDateも普通に値にアクセス出来てしまうので、使う時に注意が必要かもしれません。

まとめ

JavaにないKotlinの言語機能には、Realmと一緒に使うと便利になるようなものがいくつかあります。

生産性の上がるJVM言語Kotlinと、使いやすいモバイル向けデータベースであるRealmを組み合わせて、楽しいAndroidアプリ開発ライフを送りましょう!

明日はboohbahさんです、お楽しみに!