Realmの「タスク」サンプルアプリに実装されているリアルタイム同期を調べていました。
特に、このブロック:
private func setupNotifications() -> NotificationToken {
return parent.items.addNotificationBlock { [unowned self] changes in
switch changes {
case .Initial:
// Results are now populated and can be accessed without blocking the UI
self.viewController.didUpdateList(reload: true)
case .Update(_, let deletions, let insertions, let modifications):
// Query results have changed, so apply them to the UITableView
self.viewController.tableView.beginUpdates()
self.viewController.tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic)
self.viewController.tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic)
self.viewController.tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .None)
self.viewController.tableView.endUpdates()
self.viewController.didUpdateList(reload: false)
case .Error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError(String(error))
}
}
}
基本的に、変更はインデックスを使用して伝達されます。これらのインデックスを使用して下層のモデル/レルム オブジェクトにアクセスするだけで、インターフェイスが更新されます。
現在、これと互換性がないように見えるアーキテクチャがあります。専用のデータベース レイヤー (レルムはその実装です) があり、そこでバックグラウンド スレッドにレルム オブジェクトをロードし、プレーンなモデル オブジェクトにマップします。このようにして、コードをデータベースの実装から切り離し、不変のモデルを使用できるようにします。
この場合、インデックスを処理する方法がわかりません。元のクエリを覚えて、もう一度やり直してから、これらのインデックスを使用して必要なエントリにアクセスする必要があるように見えますか? それは非常に非効率に聞こえます...
さらに、「フィールド y でステータス x を持つすべてのアイテム」などの特定のクエリでインデックスがどのように機能するかわかりません。受け取ったインデックスはこの特定のクエリを参照していますか?
ここで続行するための推奨される方法は何ですか?
編集:コメントを追加するために、カスタムサーバーとWebソケットを使用して同期機能を実装し、インデックスの代わりにセマンティックキーを使用しました(データベースへのクエリを回避するために完全なオブジェクトを送信することもありました)。このようにして、インデックスベースのアクセスによって生じる可能性のある不整合に対処する必要がありませんでした。そのようなことが可能であるか、ある時点でレルム同期で計画されているかどうか疑問に思います.
PS 私のカスタムサーバーは十分にテストされておらず、維持するのが非常に難しいため、レルム同期に切り替えるつもりです。これが可能であることを願っています。