Skip to content

Instantly share code, notes, and snippets.

@thelbane
Last active October 13, 2017 17:05
Show Gist options
  • Save thelbane/440449e731c048173e751d83a145be9d to your computer and use it in GitHub Desktop.
Save thelbane/440449e731c048173e751d83a145be9d to your computer and use it in GitHub Desktop.
Deterministic, succinct Swift/ObjC data binding without a reactive framework.
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
class Person: NSObject {
dynamic var firstName: String
dynamic var lastName: String
init(_ fn: String, _ ln: String) {
firstName = fn
lastName = ln
}
}
class ViewModel: NSObject {
weak var delegate: ViewModelProtocol!
var person = Person("Lee","Fastenau")
var fullName: String { return "\(person.firstName) \(person.lastName)" }
init(_ delegate: ViewModelProtocol) {
super.init()
self.delegate = delegate
person.addObserver(self, forKeyPath: #keyPath(Person.firstName), options: [.new, .initial], context: nil)
person.addObserver(self, forKeyPath: #keyPath(Person.lastName), options: [.new, .initial], context: nil)
}
deinit {
person.removeObserver(self, forKeyPath: #keyPath(Person.firstName))
person.removeObserver(self, forKeyPath: #keyPath(Person.lastName))
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
delegate.fullNameChanged(self)
}
}
protocol ViewModelProtocol: class {
func fullNameChanged(_ viewModel: ViewModel)
}
class ViewController: ViewModelProtocol {
let label = UILabel()
var vm: ViewModel!
init() {
vm = ViewModel(self)
}
func fullNameChanged(_ viewModel: ViewModel) {
label.text = viewModel.fullName
}
}
let vc = ViewController()
print(vc.label.text!)
vc.vm.person.firstName = "Jack"
print(vc.label.text!)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment