[kotlin] Realmでenum型を値としたモデルを作る方法 [Android]
Realmでenum使ったモデルを作りたかったのでその方法のご紹介
How to support Enums
ヒントはこちらにありました。
cf: Enums support #776 – realm/realm-java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
open class Contract: RealmModel { enum class PaymentMethod { CREDIT_CARD, WIRE_TRANSFER } private var _paymentMethod: String? = null var paymentMethod: PaymentMethod? get() { if (_paymentMethod != null) return PaymentMethod.valueOf(_paymentMethod!!) else return null } set(value) { val realm = Realm.getDefaultInstance() realm.executeTransaction { _paymentMethod = value.toString() } realm.close() } } |
実態は_paymentMethodで、実際に使うときはpaymentMethodにアクセスしているみたいですね。
しかし、私の場合、EnumをIntにして使っていたのですが、上記のままではアクセスしたときに落ちてしまいました。
valueOfがどうやらうまく動いてない感じでした。
How to support Enums on Int
ということで、Intバージョンのモデルの作成方法のご紹介。
ヒントはこちらにありました。
1 2 3 4 5 6 7 8 |
enum class Financing(val rawValue :Int) { One(5), Revolving(6), Two(7) } // 使う Financing.values().filter { 5 == it.rawValue }.first() // => One (Financing型) Financing.values().filter { 5 == it.rawValue }.first().toString() // => One(String型) |
数字からEnum型を取り出すにはfilterとかかけてうまくやらないとだめみたいです。
なんかちょっと手間ですね。
ということで、Int版の方法で書いたモデルがこちら
1 2 3 4 5 6 7 8 9 10 11 12 |
open class Game : RealmObject() { enum class PhasePoint(val integerValue: Int) { PLAYER_READY(1), GAME_START(2) } private var phaseValue: Int = PhasePoint.PLAYER_READY.integerValue open var phase: PhasePoint get() = PhasePoint.values().filter { it.integerValue == phaseValue }.first() set(value) { phaseValue = value.integerValue } } |
こんな感じでうまくできました
まとめ
RealmでEnum対応はできるけどちょっと手間がかかってめんどくさいかもしれない。
でも、やっぱり値をちゃんと指定できてバグがなくせるのならいいかもしれない。