Logging Method signature using swift

I am trying to rewrite my logging class and I would like to know how to substitute PRETTY_FUNCTION or NSStringFromSelector(_cmd) in a swift file in order to track the method calls?


Special literals in swift are as follows (from [the swift guide]

#file String The name of the file in which it appears.

#line Int The line number on which it appears.

#column Int The column number in which it begins.

#function String The name of the declaration in which it appears.


Prior to Swift 2.2b4, these were

(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html)):

__FILE__ String The name of the file in which it appears.

__LINE__ Int The line number on which it appears.

__COLUMN__ Int The column number in which it begins.

__FUNCTION__ String The name of the declaration in which it appears.

You can use these in logging statements like so:

println("error occurred on line \(__LINE__) in function \(__FUNCTION__)")


Check out a new library I've just published: https://github.com/DaveWoodCom/XCGLogger

It's a debug logging library for Swift.

The key to being able to use the #function macros, is to set them as default values to your logging function. The compiler will then fill them in using the expected values.

func log(logMessage: String, functionName: String = #function) {
    print("\(functionName): \(logMessage)")
}

Then just call:

log("my message")

And it works as expected giving you something like:

whateverFunction(): my message

More info on how this works: https://www.cerebralgardens.com/blog/entry/2014/06/09/the-first-essential-swift-3rd-party-library-to-include-in-your-project


I'd use something like this:

func Log(message: String = "", _ path: String = __FILE__, _ function: String = __FUNCTION__) {
    let file = path.componentsSeparatedByString("/").last!.componentsSeparatedByString(".").first! // Sorry
    NSLog("\(file).\(function): \(message)")
}

Improvements compared to previous answers:

  • Uses NSLog, not print/println
  • Does not use lastPathComponent which is not available on Strings anymore
  • The log message is optional

Try this:

class Log {
    class func msg(message: String,
        functionName:  String = __FUNCTION__, fileNameWithPath: String = __FILE__, lineNumber: Int = __LINE__ ) {
        // In the default arguments to this function:
        // 1) If I use a String type, the macros (e.g., __LINE__) don't expand at run time.
        //  "\(__FUNCTION__)\(__FILE__)\(__LINE__)"
        // 2) A tuple type, like,
        // typealias SMLogFuncDetails = (String, String, Int)
        //  SMLogFuncDetails = (__FUNCTION__, __FILE__, __LINE__) 
        //  doesn't work either.
        // 3) This String = __FUNCTION__ + __FILE__
        //  also doesn't work.

        var fileNameWithoutPath = fileNameWithPath.lastPathComponent

#if DEBUG
        let output = "\(NSDate()): \(message) [\(functionName) in \(fileNameWithoutPath), line \(lineNumber)]"
        println(output)
#endif
    }
}

Log using:

let x = 100
Log.msg("My output message \(x)")