Skip to content

Instantly share code, notes, and snippets.

@max-potapov
Created May 30, 2022 18:12
Show Gist options
  • Save max-potapov/82f98df4354c9d80a34688cad545ed6a to your computer and use it in GitHub Desktop.
Save max-potapov/82f98df4354c9d80a34688cad545ed6a to your computer and use it in GitHub Desktop.
import Foundation
import RealmSwift
final class Task: Object {
@Persisted var id: String = ""
@Persisted var title: String = ""
@Persisted var text: String = ""
override static func primaryKey() -> String? { "id" }
}
final class Folder: Object {
@Persisted var id: String = ""
@Persisted var title: String = ""
@Persisted var text: String = ""
override static func primaryKey() -> String? { "id" }
}
/// make protocol with common properties
protocol EntityProperty: Object {
var title: String { get }
var text: String { get }
}
/// confirm protocol by similar realm objects
extension Task: EntityProperty {}
extension Folder: EntityProperty {}
final class EntityPropertyObserver {
var tokens: [AnyObject] = []
/// in-memory Realm to play in sandbox project
init() {
Realm.Configuration.defaultConfiguration = .init(inMemoryIdentifier: "org.mvp.RealmPlayground")
}
func observe<T: EntityProperty>(ofType: T.Type, forPrimaryKey: String, keyPath: PartialKeyPath<T>) {
do {
let realm = try Realm()
let result = realm.object(ofType: ofType, forPrimaryKey: forPrimaryKey)!
let token = result.observe(keyPaths: [keyPath], { changes in
switch changes {
case let .change(_, properties):
let keyPathName = _name(for: keyPath)
// TODO: combine or closure callback with changes
print(properties.first(where: { $0.name == keyPathName})?.newValue)
default:
break
}
})
tokens.append(token)
} catch {
fatalError("\(error)")
}
}
}
final class Playground {
let observer = EntityPropertyObserver()
init() {
// make default objects
let folder = Folder()
folder.id = "folder_id"
folder.title = "a folder title"
folder.text = "a folder text"
let task = Task()
task.id = "task_id"
task.title = "a task title"
task.text = "a task text"
do {
let realm = try Realm()
try realm.write {
realm.add(folder)
realm.add(task)
}
} catch {
fatalError("\(error)")
}
observer.observe(ofType: type(of: folder), forPrimaryKey: folder.id, keyPath: \.title)
observer.observe(ofType: type(of: task), forPrimaryKey: task.id, keyPath: \.text)
do {
let realm = try Realm()
try realm.write {
folder.title = "the title"
folder.text = "new folder text"
task.title = "yet another title"
task.text = "new task text"
}
} catch {
fatalError("\(error)")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment