Skip to content

Instantly share code, notes, and snippets.

@edwardaux
Created February 24, 2017 07:18
Show Gist options
  • Save edwardaux/60c106ab6876c3c3c16216ae8d714108 to your computer and use it in GitHub Desktop.
Save edwardaux/60c106ab6876c3c3c16216ae8d714108 to your computer and use it in GitHub Desktop.
A simple expression watcher for Swift apps
// Sometimes you want to watch a particular expression over time. Continually dumping
// the value in a loop can be painful because of the sheer volume of values. This snippet
// loops on a background thread checking the result of the passed expression - if the
// value changes (and only then) does it output the new value. Note that this is NOT meant
// as a replacement for a KVO-observable property... it is better suited to expressions
// that do not post KVO events.
//
// Usage: watchExpression(every: 0.1) { someCodeThatReturnsAValue() }
//
// You can control how often the value will be checked using the every parameter (the example
// above checks every 100ms). The return value can be any object that conforms to the
// Equatable protocol.
//
// Note that this is NOT meant to be left in production code. It is purely meant to be
// a debugging tool.
var timer: DispatchSourceTimer?
func watchExpression<T: Equatable>(every: TimeInterval, expression: @escaping () -> T?) {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss.SSS"
formatter.timeZone = TimeZone.current
func dump(value: T?) {
let output: Any = value ?? "nil"
let time = formatter.string(from: Date())
print(">>> \(time) \(output)")
}
var previousValue = expression()
dump(value: previousValue)
let queue = DispatchQueue(label: "expression.watcher", attributes: .concurrent)
timer?.cancel()
timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
timer?.scheduleRepeating(deadline: .now(), interval: every)
timer?.setEventHandler {
let currentValue = expression()
if currentValue != previousValue {
dump(value: currentValue)
previousValue = currentValue
}
}
timer?.resume()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment