Skip to content

Instantly share code, notes, and snippets.

@ivanfoong
Last active December 5, 2017 02:13
Show Gist options
  • Save ivanfoong/63a378fb48e9b81ac1bd8092e5bb7ec7 to your computer and use it in GitHub Desktop.
Save ivanfoong/63a378fb48e9b81ac1bd8092e5bb7ec7 to your computer and use it in GitHub Desktop.
Generic wrapper for Observable values
class ViewModel {
var content: Observable<String?> = Observable(nil)
func seedContent() {
self.content.value = "Seeded content"
}
}
class ExampleViewController {
@IBOutlet weak var contentTextField: UITextField!
let viewModel = ViewModel()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.viewModel.content.bind(for: self, initialFire: true) { newContent in
self.contentTextField.text = newContent
}
self.viewModel.seedContent()
}
}
//
// Observable.swift
//
// Created by Ivan Foong on 1/12/17.
// Copyright © 2017 Ivan Foong. All rights reserved.
//
import Foundation
class Observable<T> {
typealias ObservableListener = (T) -> Void
private var listeners: [AnyHashable: ObservableListener] = [:]
func bind(for context: AnyHashable, initialFire: Bool = false, with listener: ObservableListener?) {
self.listeners[context] = listener
if initialFire {
listener?(value)
}
}
func unbind(for context: AnyHashable) {
self.listeners.removeValue(forKey: context)
}
var value: T {
didSet {
if value != oldValue {
self.listeners.values.forEach { listener in
listener(value)
}
}
}
}
init(_ value: T) {
self.value = value
}
}
@kajalsinha
Copy link

need to check if old and new values are not same. if not same then only notify the listeners.

@kajalsinha
Copy link

initialFire parameter is unused. we can use it to send initial state to newly registered observer.

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