Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Created September 11, 2017 13:21
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save chriseidhof/f365e3d70bc6526e5aab454e4d651c3b to your computer and use it in GitHub Desktop.
Save chriseidhof/f365e3d70bc6526e5aab454e4d651c3b to your computer and use it in GitHub Desktop.
import Foundation
final class Sample: NSObject {
@objc dynamic var name: String = ""
}
class MyObj: NSObject {
@objc dynamic var test: String = ""
}
extension NSObjectProtocol where Self: NSObject {
func observe<A, Other>(_ keyPath: KeyPath<Self,A>,
writeTo other: Other,
_ otherKeyPath: ReferenceWritableKeyPath<Other,A>)
-> NSKeyValueObservation
where A: Equatable, Other: NSObjectProtocol {
return self.observe(keyPath, options: .new) { _, change in
guard let newValue = change.newValue,
other[keyPath: otherKeyPath] != newValue else {
return // no change
}
other[keyPath: otherKeyPath] = newValue
}
}
func bind<A, Other>(_ keyPath: ReferenceWritableKeyPath<Self,A>,
to other: Other,
_ otherKeyPath: ReferenceWritableKeyPath<Other,A>)
-> (NSKeyValueObservation, NSKeyValueObservation)
where A: Equatable, Other: NSObject
{
let one = self.observe(keyPath, writeTo: other, otherKeyPath)
let two = other.observe(otherKeyPath, writeTo: self, keyPath)
return (one,two)
}
}
let sample = Sample()
let other = MyObj()
let observation = sample.bind(\Sample.name, to: other, \.test)
sample.name = "NEW"
other.test
other.test = "HI"
sample.name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment