Skip to content

Instantly share code, notes, and snippets.

@justinlevi
Last active January 24, 2016 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinlevi/c408c4aa043c46768c3d to your computer and use it in GitHub Desktop.
Save justinlevi/c408c4aa043c46768c3d to your computer and use it in GitHub Desktop.
import Foundation
// ============================================
// MARK: - KVObserver Helper
// Modified from Source : https://stackoverflow.com/questions/27292918
class KVObserver: NSObject {
private let keyPath: String
private let block: () -> Void
private weak var object: AnyObject?
init(_ object: AnyObject, keyPath: String, block: () -> Void) {
self.object = object
self.keyPath = keyPath
self.block = block
super.init()
object.addObserver(self, forKeyPath: keyPath, options: .New, context: nil);
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == self.keyPath {
block()
}
}
deinit {
object?.removeObserver(self, forKeyPath: keyPath)
}
}
// ============================================
// MARK: - NSObject Subclass Defining enum to observe
// Must subclass NSObject for KVObserver to work
class MainViewModel: NSObject {
enum ApplicationState: String {
case Default, Ready, Set, Go
}
dynamic private(set) var applicationStateRaw: String?
var applicationState: ApplicationState? {
didSet { applicationStateRaw = applicationState?.rawValue }
}
}
// ============================================
// MARK: - This could just as easily be your MainViewController
class Main: NSObject {
let mainViewModel = MainViewModel()
var applicationStateObserver: KVObserver!
override init() {
super.init()
applicationStateObserver = KVObserver(mainViewModel, keyPath: "applicationStateRaw") { [unowned self] in
guard let state = self.mainViewModel.applicationState else { return }
switch state {
case .Default: print("DEFAULT")
case .Ready: print("READY")
case .Set: print("SET")
case .Go: print("GO")
}
}
}
deinit {
applicationStateObserver = nil
}
}
let main = Main()
main.mainViewModel.applicationState = .Ready
main.mainViewModel.applicationState = .Go
@justinlevi
Copy link
Author

ToDo: Need to explore if this could be optimized/refactored to use @NoEscape in order to remove the need for [unowned self].
http://krakendev.io/blog/hipster-swift#noescape

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