Skip to content

Instantly share code, notes, and snippets.

@philosopherdog
Forked from chriseidhof/kvo-binding.swift
Created April 18, 2021 18:08
Show Gist options
  • Save philosopherdog/1ee8af7175841e4fe2fb75ad320cfce7 to your computer and use it in GitHub Desktop.
Save philosopherdog/1ee8af7175841e4fe2fb75ad320cfce7 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