Woody is a micro logging framework with support for Swift & Objective-C that helps decouple which logging framework the end client (usually an app) would like to use. For example you have multiple in house frameworks which are used across multiple different apps and you don't want to tie them all to a specific logging framework like CocoaLumberjack or SwiftyBeaver. Woody allows you to not worry about which logging framework your app team wants to use when developing those in house frameworks and instead leaves that up to the end consumer of your framework.
import Woody
let log = Woody.self
log.verbose("Verbose message")
log.info("Info message")
log.debug("Debug message")
log.warning("Warning message")
log.error("Error message")
@import Woody;
WLogVerbose(@"Verbose message");
WLogInfo(@"Info message");
WLogDebug(@"Debug message");
WLogWarning(@"Warning message");
WLogError(@"Error message");
This library supports both Carthage and CocoaPods
Add this line to your Podfile
pod 'Woody'
Add this line to your Cartfile
github "vivint/Woody" ~> 0.2.0
Below are two guides for use in either a framework or app target
The easiest way to get started using Woody in a framework is to add a Logging.swift
file like this:
import Foundation
import Woody
let log = Woody.self
// Mark these as deprecated to make sure we don't forget to use Woody logging
@available(*, deprecated, message: "Use logging utilities instead")
func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Swift.print(items, separator: separator, terminator: terminator)
}
@available(*, deprecated, message: "Use logging utilities instead")
func debugPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Swift.debugPrint(items, separator: separator, terminator: terminator)
}
@available(*, deprecated, message: "Use logging utilities instead")
func NSLog(_ format: String, _ args: CVarArg...) {
Foundation.NSLog(format, args)
}
The easiest way to setup logging in an app is to add a AppDelegate+Logging.swift
file and adding the following items:
This sets up an easy way to log throughout the app
import Woody
let log = Woody.self
I have found these useful to make sure other developers of the project are using the logging methods instead of any built in ones.
import Foundation
// Mark these as deprecated to make sure we don't forget to use logging in the app
@available(*, deprecated, message: "Use logging utilities instead")
func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Swift.print(items, separator: separator, terminator: terminator)
}
@available(*, deprecated, message: "Use logging utilities instead")
func debugPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Swift.debugPrint(items, separator: separator, terminator: terminator)
}
@available(*, deprecated, message: "Use logging utilities instead")
func NSLog(_ format: String, _ args: CVarArg...) {
Foundation.NSLog(format, args)
}
You need to setup a delegate to get called whenever a log happens
class LoggingDelegate: WoodyDelegate {
func verbose(_ msg: String, filepath: String, function: String, line: Int) {
print("VERBOSE: \(filepath).\(function): \(line) - \(msg)")
}
func debug(_ msg: String, filepath: String, function: String, line: Int) {
print("DEBUG: \(filepath).\(function): \(line) - \(msg)")
}
func info(_ msg: String, filepath: String, function: String, line: Int) {
print("INFO: \(filepath).\(function): \(line) - \(msg)")
}
func warning(_ msg: String, filepath: String, function: String, line: Int) {
print("WARNING: \(filepath).\(function): \(line) - \(msg)")
}
func error(_ msg: String, filepath: String, function: String, line: Int) {
print("ERROR: \(filepath).\(function): \(line) - \(msg)")
}
}
Extend the AppDelegate
to add a method to setup logging
extension AppDelegate {
func setupLogging() {
log.delegate = LoggingDelegate()
}
}
Last of all you need to call you new setupLogging()
method in your appDidFinishLaunching
. (I would put it at the very top so you don't miss any logs when the app is launching)
If you would like to forward the logs on to a different provider like SwiftyBeaver you can easily do that in your WoodyDelegate
import SwiftyBeaver
class LoggingDelegate: WoodyDelegate {
func verbose(_ msg: String, filepath: String, function: String, line: Int) {
SwiftyBeaver.verbose(msg, filepath, function, line: line)
}
func debug(_ msg: String, filepath: String, function: String, line: Int) {
SwiftyBeaver.debug(msg, filepath, function, line: line)
}
func info(_ msg: String, filepath: String, function: String, line: Int) {
SwiftyBeaver.info(msg, filepath, function, line: line)
}
func warning(_ msg: String, filepath: String, function: String, line: Int) {
SwiftyBeaver.warning(msg, filepath, function, line: line)
}
func error(_ msg: String, filepath: String, function: String, line: Int) {
SwiftyBeaver.error(msg, filepath, function, line: line)
}
}
And then in your setupLogging()
you can add some Destinations to SwiftyBeaver
extension AppDelegate {
func setupLogging(logLevel: SwiftyBeaver.Level = .verbose) {
log.delegate = LoggingDelegate()
let console = ConsoleDestination()
// use custom format and set console output to short time, log level & message
console.format = "$C$L$c $N.$F:$l - $M"
console.minLevel = logLevel
SwiftyBeaver.addDestination(console)
let cloud = SBPlatformDestination(appID: "APP_ID", appSecret: "SECRET", encryptionKey: "KEY")
cloud.minLevel = logLevel
SwiftyBeaver.addDestination(cloud)
}
}
- Give the ability to users of Woody register themselves as Woody consumer and allow the end user to filter out logs for each framework that has registered.
- Possibly send logs to console by default if no
WoodyDelegate
is set.