Skip to content

Instantly share code, notes, and snippets.

@GeekTree0101
Last active February 27, 2020 03:12
Show Gist options
  • Save GeekTree0101/ed6a9ea65504f088c506a0838a5a8b73 to your computer and use it in GitHub Desktop.
Save GeekTree0101/ed6a9ea65504f088c506a0838a5a8b73 to your computer and use it in GitHub Desktop.
Domain Model Syncronizer
protocol Syncronizable {
func isSyncronizable(from value: Self?) -> Bool
}
class Syncronizer {
static let shared = Syncronizer()
private var contexts: [String: (Any?) -> Void] = [:]
public func publish(id: String, model: Any?) {
contexts.forEach({ target, callback in
guard id != target else { return }
callback(model)
})
}
public func register(id: String, callback: @escaping (Any?) -> Void) {
contexts[id] = callback
}
public func unregister(id: String) {
contexts[id] = nil
}
}
@propertyWrapper
class Syncronize<T: Syncronizable> {
private var value: T?
private let id: String
deinit {
Syncronizer.shared.unregister(id: id)
}
init(value: T?, compare: ((T, T?) -> Bool)? = nil) {
self.value = value
self.id = "\(Date().timeIntervalSince1970)" // unique identifier
Syncronizer.shared.register(id: id, callback: { model in
guard let newValue = model as? T else { return }
guard self.value?.isSyncronizable(from: newValue) == true else { return }
guard compare?(newValue, self.value) ?? true == true else { return }
self.value = newValue
})
}
var wrappedValue: T? {
get {
return value
}
set {
self.value = newValue
Syncronizer.shared.publish(id: id, model: value)
}
}
}
@Syncronize(value: nil)
var card: Card?
@Syncronize(value: Card(id: 1, title: "what"))
var card2: Card?
@Syncronize(value: Card(id: 1, title: "what", content: "a"), compare: { prev, source -> Bool in
return prev.content != source?.content
})
var card3: Card?
card = Card(id: 1, title: "hello", content: "a", isFollow: true)
print(card?.title) // hello
print(card2?.title) // what -> hello
print(card3?.title) // what , doesn't change! due to content
@GeekTree0101
Copy link
Author

사용하면 Domain Model은 반드시 Syncronizable 를 상속받아야합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment