RealmのDBの変更を通知してObservableを作成できるRxRealm便利すぎる


モバイルDBの主流であるReamlのDBの変更を検知できるRxRealmが便利すぎるのでご紹介します。
Realmの参考: CarthageでRealmを導入する

RxRealmについて

RxRealmはRealmのDBの変更を検知しObservableを作成できる便利なライブラリです。
導入はCarthageでもCocoaPodsでもどちらでも可能です。
Github

使い方

変更後のDBの値を受け取る

DBの変更を検知して、変更後のDBの値を受け取ります。

1. Results, List, LinkingObjects, AnyRealmCollectionで受け取る

let realm = try! Realm()
// Scheduleは作成した任意のObject
let object = realm.objects(Schedule.self)

Observable.collection(from: object)
    .subscribe(onNext: { item in
        // item: 変更後のobjectの一覧
        // 型: Results,List,LinkingObjects,AnyRealmCollection
        print(item)
    })
    .disposed(by: disposeBag)

Resultで受けとた場合のアウトプット👇

Results<Schedule> <0x137f7d920> (
    [0] Schedule {
        no = 3;
        name = 追加;
        date = 2021-02-08 12:13:55 +0000;
        notificate = 0;
    }
)

2. arrayで受け取る

let realm = try! Realm()
let object = realm.objects(Schedule.self)

Observable.array(from: object)
    .subscribe(onNext: { item  in
        // item: 変更後のobjectの一覧
        // 型: array
        print(item)
    })
    .disposed(by: disposeBag)

アウトプット👇

[Schedule {
    no = 0;
    name = 追加;
    date = 2021-02-12 13:51:43 +0000;
    notificate = 0;
}]

変更後のDBの値+アクションの種類を受け取る

変更後のDBの値に加え、アクションの種類(delete, inserted, updated)を受け取れる。

1. Results, List, LinkingObjects, AnyRealmCollectionで受け取る

Observable.changeset(from: object)
    .subscribe(onNext: { results, changes in
        if let changes = changes {
            // changes: 検知したアクションの一覧
            print("deleted: \(changes.deleted)")
            print("inserted: \(changes.inserted)")
            print("updated: \(changes.updated)")
            print("-----------------------")
            // results: 変更後のobjectの一覧
            print(results)
        } else {
            // results: 変更後のobjectの一覧
            print(results)
        }
     })
    .disposed(by: disposeBag)

insertのアウトプット👇

deleted: []
inserted: [0]
updated: []
-----------------------
Results<Schedule> <0x13ff3b2c0> (
    [0] Schedule {
        no = 0;
        name = 追加;
        date = 2021-02-12 13:56:38 +0000;
        notificate = 0;
    }
)

2. arrayで受け取る

Observable.arrayWithChangeset(from: object)
    .subscribe(onNext: { array, changes in
        if let changes = changes {
            // changes: 検知したアクションの一覧
            print(array.first)
            print("deleted: \(changes.deleted)")
            print("inserted: \(changes.inserted)")
            print("updated: \(changes.updated)")
            print("-----------------------")
            // array: 変更後のobjectの一覧
            print(array)
            } else {
                // array: 変更後のobjectの一覧
                print(array)
            }
    })
    .disposed(by: disposeBag)

updateのアウトプット👇

deleted: []
inserted: []
updated: [0]
[Schedule {
    no = 0;
    name = 追加→更新;
    date = 2021-02-07 14:03:57 +0000;
    notificate = 0;
}]

まとめ

RxRealmを使うことによって、すごく簡単にDBの変更を検知できますね。
DBの値を元に画面の描画を行っている時(特にTableViewとか多いと思いますが)におすすめです。
ぜひ使ってみてください。