Created
May 30, 2022 18:12
-
-
Save max-potapov/82f98df4354c9d80a34688cad545ed6a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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