-
-
Save Abizern/a81f31a75e1ad98ff80d to your computer and use it in GitHub Desktop.
// | |
// LoggingPrint.swift | |
// | |
import Foundation | |
/** | |
Prints the filename, function name, line number and textual representation of `object` and a newline character into | |
the standard output if the build setting for "Active Complilation Conditions" (SWIFT_ACTIVE_COMPILATION_CONDITIONS) defines `DEBUG`. | |
The current thread is a prefix on the output. <UI> for the main thread, <BG> for anything else. | |
Only the first parameter needs to be passed to this funtion. | |
The textual representation is obtained from the `object` using `String(reflecting:)` which works for _any_ type. | |
To provide a custom format for the output make your object conform to `CustomDebugStringConvertible` and provide your format in | |
the `debugDescription` parameter. | |
:param: object The object whose textual representation will be printed. If this is an expression, it is lazily evaluated. | |
:param: file The name of the file, defaults to the current file without the ".swift" extension. | |
:param: function The name of the function, defaults to the function within which the call is made. | |
:param: line The line number, defaults to the line number within the file that the call is made. | |
*/ | |
func loggingPrint<T>(_ object: @autoclosure () -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line) { | |
#if DEBUG | |
let value = object() | |
let fileURL = NSURL(string: file)?.lastPathComponent ?? "Unknown file" | |
let queue = Thread.isMainThread ? "UI" : "BG" | |
print("<\(queue)> \(fileURL) \(function)[\(line)]: " + String(reflecting: value)) | |
#endif | |
} |
Do you have example uses cases or codes for calling this method?
Yep. I use it instead of print() while developing - prints to the console only for debug builds.
Updated for Swift 2.0
@Abizern Do you have example how to use this, I add the custom flag but I don't see the logs, I'm running on Xcode 7.2 IOS 9.2 simulator
Thanks for this @Abizern! XCode 7.3 is suggesting to replace soon-to-be-deprecated __FILE__
, __FUNCTION__
, and __LINE__
with #file
, #function
and #line
, like so:
func loggingPrint<T>(@autoclosure object: () -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
@Abizern Also, it would be super if you could clarify the licence - thanks!
Swift 3.0 version will look like this:
func loggingPrint<T>(object: @autoclosure () -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
#if DEBUG
let value = object()
let stringRepresentation: String
if let value = value as? CustomDebugStringConvertible {
stringRepresentation = value.debugDescription
} else if let value = value as? CustomStringConvertible {
stringRepresentation = value.description
} else {
fatalError("loggingPrint only works for values that conform to CustomDebugStringConvertible or CustomStringConvertible")
}
let fileURL = URL(string: file)?.lastPathComponent ?? "Unknown file"
let queue = Thread.isMainThread ? "UI" : "BG"
print("<\(queue)> \(fileURL) \(function)[\(line)]: " + stringRepresentation)
#endif
}
I'm also interested in the license. :)
An enhanced solution might look like this:
func loggingPrint<T>(_ closure: @autoclosure () -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
#if DEBUG
let instance = closure()
let description: String
if let debugStringConvertible = instance as? CustomDebugStringConvertible {
description = debugStringConvertible.debugDescription
} else {
// Will use `CustomStringConvertible` representation if possuble, otherwise
// it will print the type of the returned instance like `T()`
description = "\(instance)"
}
let file = URL(fileURLWithPath: file).lastPathComponent
let queue = Thread.isMainThread ? "UI" : "BG"
print("<\(queue)> \(file) `\(function)` [\(line)]: \(description)")
#endif
}
Sorry @DevAndArtist and @paulfurley, I completely missed your questions. I've updated the gist to Swift 3 and Xcode 8, which allowed me to simplify the code and also provides a different way of specifiying DEBUG.
The License is MIT, and you can see a proper repository (rather than a gist) over at https://github.com/JungleCandy/LoggingPrint.
Even if i run the build in release configuration i can see all the Logs in Console ... Any idea ? i am using Xcode 9.2 and iOS 11.x
Explanation available at http://abizern.org/2015/02/01/debug-logging-in-swift/