How to use Crashlytics logging in Swift? How to use Crashlytics logging in Swift? ios ios

How to use Crashlytics logging in Swift?


Mike from Crashlytics here.

To use custom logging in Swift, just use CLSLogv or CLSNSLogv. You need to make an array and then call getVaList function on that array.

Here's a snippet:

CLSLogv("Log something %d %d %@", getVaList([1, 2, "three"]))

For CLSNSLogv:

CLSNSLogv("hello %@", getVaList(["goodbye"]))


Here is my version adapted from Dima's answer. I have no need of the arguments, since you can do all the formatting within the Swift string that you pass.

func DebugLog(_ message: String, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {    let output: String    if let filename = URL(fileURLWithPath: file.description).lastPathComponent.components(separatedBy: ".").first {        output = "\(filename).\(function) line \(line) $ \(message)"    } else {        output = "\(file).\(function) line \(line) $ \(message)"    }    #if targetEnvironment(simulator)        NSLogv("%@", getVaList([output]))    #elseif DEBUG        CLSNSLogv("%@", getVaList([output]))    #else        CLSLogv("%@", getVaList([output]))    #endif}

And you would use it like this:

DebugLog("this is a log message")DebugLog("this is a log message \(param1) \(param2)")

EDIT: Updated to Swift 3.1


I needed something similar to CLS_LOG() in Swift that printed out contextual information about the location of the call. Normally this would not be possible without preprocessor directives but I found out how to replicate this behavior pretty closely in Swift here:https://developer.apple.com/swift/blog/?id=15

The identifiers we need (#file, #function, #line) show information about the caller if you set them as default values in an argument list.

Note: If you are logging errors that may have % symbols in them, such as network query strings, this may crash. You'll need to join the string first (e.g. let string = "\(filename).\(function) line \(line) $ \(message)")

Swift 3 version (note: this is a global function, so it should be placed outside of any struct or class definition):

/// Usage:////// CLS.log("message!")/// CLS.log("message with parameter 1: %@ and 2: %@", ["First", "Second"])///func CLS_LOG_SWIFT(format: String = "", _ args: [CVarArg] = [], file: String = #file, function: String = #function, line: Int = #line) {    let filename = URL(string: file)?.lastPathComponent.components(separatedBy: ".").first    #if DEBUG        CLSNSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))    #else        CLSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))    #endif}

Swift 2 version:

// CLS_LOG_SWIFT()// CLS_LOG_SWIFT("message!")// CLS_LOG_SWIFT("message with parameter 1: %@ and 2: %@", ["First", "Second"])func CLS_LOG_SWIFT(format: String = "",    _ args:[CVarArgType] = [],    file: String = __FILE__,    function: String = __FUNCTION__,    line: Int = __LINE__){    let filename = NSURL(string:file)?.lastPathComponent?.componentsSeparatedByString(".").first    #if DEBUG        CLSNSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))    #else        CLSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))    #endif}// CLS_LOG() output: -[ClassName methodName:] line 10 $// CLS_LOG_SWIFT() output: ClassName.methodName line 10 $

And here is a gist with some more information and the actual file I put this code in: https://gist.github.com/DimaVartanian/a8aa73ba814a61f749c0

As you can see it is pretty close to the original macro and only differs in that you can't see if you are calling a class method or an instance method, and that you need to include your format argument list enclosed in an array. Both are limitations I believe there is no way around right now but pretty minor. You also need to make sure DEBUG is defined in your Swift compiler flags. It does not carry over from your regular flags automatically.