Я пытаюсь переписать мой класс ведения журнала, и я хотел бы знать, как заменить PRETTY_FUNCTION или NSStringFromSelector (_cmd) в быстром файле, чтобы отслеживать вызовы метода?
Подпись метода ведения журнала с использованием быстрой
Ответ 1
Откройте новую библиотеку, которую я только что опубликовал: https://github.com/DaveWoodCom/XCGLogger
Это библиотека журнала отладки для Swift.
Ключом к возможности использования макросов #function
является установка их в качестве значений по умолчанию для вашей функции ведения журнала. Затем компилятор заполнит их, используя ожидаемые значения.
func log(logMessage: String, functionName: String = #function) {
print("\(functionName): \(logMessage)")
}
Затем просто позвоните:
log("my message")
И он работает как ожидалось, давая вам что-то вроде:
whateverFunction(): my message
Дополнительная информация о том, как это работает: http://www.cerebralgardens.com/blog/entry/2014/06/09/the-first-essential-swift-3rd-party-library-to-include-in-your-project
Ответ 2
Специальные литералы в быстрой форме следующие (из [быстрого руководства]
#file
Строка Имя файла, в котором он отображается.
#line
Int Номер строки, на которой он отображается.
#column
Int Номер столбца, в котором он начинается.
#function
Строка Имя объявления, в котором оно отображается.
До Swift 2.2b4 это были
__FILE__
String Имя файла, в котором он отображается.
__LINE__
Int Номер строки, на которой он отображается.
__COLUMN__
Int Номер столбца, в котором он начинается.
__FUNCTION__
Строка Имя объявления, в котором оно отображается.
Вы можете использовать их в операторах ведения журнала следующим образом:
println("error occurred on line \(__LINE__) in function \(__FUNCTION__)")
Ответ 3
Я бы использовал что-то вроде этого:
func Log(message: String = "", _ path: String = __FILE__, _ function: String = __FUNCTION__) {
let file = path.componentsSeparatedByString("/").last!.componentsSeparatedByString(".").first! // Sorry
NSLog("\(file).\(function): \(message)")
}
Улучшения по сравнению с предыдущими ответами:
- Использует NSLog, а не print/println
- Не использует lastPathComponent, который больше не доступен для строк.
- Сообщение журнала необязательно
Ответ 4
Попробуйте следующее:
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
}
}
Журнал с использованием:
let x = 100
Log.msg("My output message \(x)")
Ответ 5
Вот что я использовал в: https://github.com/goktugyil/QorumLogs
Это похоже на XCGLogger, но лучше.
func myLog<T>(object: T, _ file: String = __FILE__, _ function: String = __FUNCTION__, _ line: Int = __LINE__) {
let info = "\(file).\(function)[\(line)]:\(object)"
print(info)
}
Ответ 6
Для Swift 3 и выше:
print("\(#function)")
Ответ 7
С Swift 2.2 вы можете указать его с помощью Literal Expressions
, как описано в Руководство по языку Swift Programming.
Итак, если у вас была структура Logger
, у которой была функция, которая регистрировалась там, где произошла ошибка, вы бы назвали ее следующим образом:
Logger().log(message, fileName: #file, functionName: #function, atLine: #line)
Ответ 8
Это даст вам класс и имя функции за один раз:
var name = NSStringFromClass(self.classForCoder) + "." + __FUNCTION__
Ответ 9
Это будет печататься только в режиме отладки:
func debugLog(text: String, fileName: String = __FILE__, function: String = __FUNCTION__, line: Int = __LINE__) {
debugPrint("[\((fileName as NSString).lastPathComponent), in \(function)() at line: \(line)]: \(text)")
}
Результат:
"[Book.swift, in addPage() at line: 33]: Page added with success"
Ответ 10
похоже, что он отлично работает в быстром 3.1
print("File: \((#file as NSString).lastPathComponent) Func: \(#function) Line: \(#line)")
Ответ 11
Swift 3 поддерживает объект debugLog с датой, именем функции, именем файла, номером строки:
public func debugLog(object: Any, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
let className = (fileName as NSString).lastPathComponent
print("\(NSDate()): <\(className)> \(functionName) [#\(lineNumber)]| \(object)\n")
}
Ответ 12
Появилась новая библиотека, которую я опубликовал: Принтер.
Он имеет множество функций, позволяющих вам входить в систему разными способами.
Чтобы зарегистрировать успешное сообщение:
Printer.log.success(details: "This is a Success message.")
Вывод:
Printer ➞ [✅ Success] [⌚04-27-2017 10:53:28] ➞ ✹✹This is a Success message.✹✹
[Trace] ➞ ViewController.swift ➞ viewDidLoad() #58
Отказ от ответственности. Эта библиотека была создана мной.
Ответ 13
Здесь я принимаю это.
func Log<T>(_ object: Shit, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
var filename = (file as NSString).lastPathComponent
filename = filename.components(separatedBy: ".")[0]
let currentDate = Date()
let df = DateFormatter()
df.dateFormat = "HH:mm:ss.SSS"
print("┌──────────────┬───────────────────────────────────────────────────────────────")
print("│ \(df.string(from: currentDate)) │ \(filename).\(function) (\(line))")
print("└──────────────┴───────────────────────────────────────────────────────────────")
print(" \(object)\n")}
Надеюсь, вам понравится.
Ответ 14
func Log<T>(_ object: T, fileName: String = #file, function: String = #function, line: Int = #line) {
NSLog("\((fileName as NSString).lastPathComponent), in \(function) at line: \(line): \(object)")
}