Skip to content

Instantly share code, notes, and snippets.

@garohussenjian
Created January 18, 2019 06:08
Show Gist options
  • Save garohussenjian/e6bfc021798f5b91f022d5c001d8b0df to your computer and use it in GitHub Desktop.
Save garohussenjian/e6bfc021798f5b91f022d5c001d8b0df to your computer and use it in GitHub Desktop.
import Foundation
import PlaygroundSupport
import UIKit
public protocol Logger {
func log(_ values: Any...)
}
extension Logger {
public func log(_ values: Any...) {
LiveViewLogger.shared.output(values)
}
}
public final class LiveViewLogger {
public enum OutputView {
case liveView, debugArea
}
public static var shared: LiveViewLogger = .init()
private var startTime: TimeInterval
private var runningTime: TimeInterval {
return Date.timeIntervalSinceReferenceDate - startTime
}
private let loggerView: UITextView = {
let frame = CGRect(x: 0, y: 0, width: 640, height: 954)
let textView = UITextView(frame: frame)
textView.backgroundColor = .init(red: 0.1176470588,
green: 0.1254901961,
blue: 0.1568627451,
alpha: 1)
textView.textColor = .white
textView.font = .monospacedDigitSystemFont(ofSize: 14, weight: .regular)
textView.isEditable = false
textView.textContainerInset = .init(top: 8, left: 8, bottom: 8, right: 8)
return textView
}()
public var outputView: OutputView = .debugArea {
didSet {
if outputView == .liveView {
PlaygroundPage.current.liveView = loggerView
}
}
}
private var outputString: String = ""
public init() {
PlaygroundPage.current.needsIndefiniteExecution = true
startTime = Date.timeIntervalSinceReferenceDate
}
public func start(liveView: Bool = false) -> Self {
if liveView { outputView = .liveView }
startTime = Date.timeIntervalSinceReferenceDate
return self
}
public func log(_ values: Any...) -> Self {
output(values)
output("--")
return self
}
public func tick() -> Self {
output("\(Int(runningTime * 1_000)) msec")
return self
}
public func measure(
_ label: String? = nil,
_ work: (_ log: (Any...) -> Void) -> Void) -> Self {
if let label = label {
output("\(label)")
}
let taskStartTime = Date.timeIntervalSinceReferenceDate
work(output)
let elapsedTime = Date.timeIntervalSinceReferenceDate - taskStartTime
tick(elapsedTime)
output("--")
return self
}
public func output(_ value: Any) {
output([value])
}
public func output(_ values: Any...) {
output(values)
}
fileprivate func output(_ values: [Any]) {
let strings = values
.map { "\($0)" }
.joined(separator: " ")
if outputView == .liveView {
outputString += "\(strings)\n"
} else {
print(strings)
}
}
private func tick(_ elapsedTime: TimeInterval) {
output("\(Int(elapsedTime * 1_000)) of \(Int(runningTime * 1_000)) msec")
}
public func end() {
output("Completed in \(Int(runningTime * 1_000)) msec")
if outputView == .liveView {
loggerView.text = outputString
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment