Отключение NSLog для производства в Swift Project
Итак, этот ответ Нужно ли отключать NSLog перед выпуском приложения? дает отличный способ отключить NSLog в рабочей среде, но, к сожалению, это решение не кажется для работы над проектами Swift. Мой подход состоял в том, чтобы поместить следующий код в заголовок .h файла, который я использую для некоторых модулей в моем проекте.
#ifdef DEBUG
#define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
#define DLog(...) do { } while (0)
#endif
Однако использование DLog в коде Swift приводит к тому, что компилятор заявляет, что они являются нераспознанными символами. Где-то еще я должен разместить этот #ifdef
или есть другое решение для проекта Swift вообще?
Ответы
Ответ 1
Вам нужно настроить флаг компилятора для использования препроцессора Swift - перейдите в раздел Swift Compiler - Custom Flags в разделе "Настройки сборки", чтобы установить флаг -D DEBUG
:
![DEBUG flag]()
Затем в вашем коде вы можете определить функцию DLog()
и только распечатать свое сообщение, если установлен флаг DEBUG
:
func DLog(message: String, function: String = #function) {
#if DEBUG
println("\(function): \(message)")
#endif
}
Ответ 2
Я довольно продвинутый разработчик и нуждаюсь в чём-то определенном, немного более четко, чтобы следовать за ним. У меня возникли проблемы с аналогичной проблемой, вместо этого заменив println(), и когда я задал этот вопрос, мой запрос был помечен как дубликат этого вопроса.
После многих исследований, испытаний, ошибок, ошибок, ошибок и ошибок ERROR!, я обнаружил, что последовательность, которую мне нужно выполнить, следующая:
- Нажмите название проекта в верхней части Файлового навигатора слева от окна проекта Xcode. Это строка с именем проекта, количеством целей сборки и версией iOS для SDK.
- Выберите вкладку Настройки сборки и прокрутите вниз до раздела " Swift Compiler - Custom Flags" внизу. Нажмите стрелку вниз рядом с Другие флаги, чтобы развернуть раздел.
- Нажмите на строку Отладка, чтобы выбрать ее. Наведите указатель мыши на правую сторону линии и дважды щелкните мышью. Появится список. Нажмите кнопку + в левом нижнем углу списка, чтобы добавить значение. Текстовое поле станет активным.
- В текстовом поле введите текст
-D DEBUG
и нажмите Вернуть, чтобы зафиксировать строку.
-
Добавить новый файл Swift в ваш проект. Вы захотите создать пользовательский класс для файла, поэтому введите текст по строкам следующего вида:
class Log {
var intFor : Int
init() {
intFor = 42
}
func DLog(message: String, function: String = __FUNCTION__) {
#if DEBUG
println("\(function): \(message)")
#endif
}
}
(У меня возникла проблема с тем, что сегодня для Xcode был принят класс init, поэтому init может быть немного тяжелее, чем необходимо.)
-
Теперь вам нужно будет ссылаться на свой пользовательский класс в любом классе, в котором вы намерены использовать новую настраиваемую функцию вместо println()
Добавить это как свойство в каждом применимом классе:
let logFor = Log()
-
Теперь вы можете заменить любые экземпляры println()
на logFor.DLog()
. Вывод также включает имя функции, в которой была вызвана строка.
- Обратите внимание, что внутри функций класса я не мог вызывать функцию, если только я не сделал копию функции как функцию класса в этом классе, а
println()
также немного более гибким с вводом, поэтому я не мог используйте это в каждом экземпляре в моем коде.
Ответ 3
Ознакомьтесь с записью в блоге Apple Swift о записи здесь
Вкратце, ответ заключается в том, чтобы написать DLog как:
func DLog(message:String, function:String = __FUNCTION__) {
#if !NDEBUG
NSLog("%@, %@", function, message)
#endif
}
Ответ 4
Я только что нашел эту удивительную глобальную функцию:
https://gist.github.com/Abizern/a81f31a75e1ad98ff80d
Это соответствует ответу Nate Cook и дополнительно печатает имя файла и номер строки найденного отчета отладки печати.
Ответ 5
Ниже я изменил ответ Nate Cook, приведенный выше. Эта версия работает как с аргументами String
, так и NSString
:
func DLog<T>(message:T, function: String = __FUNCTION__) {
#if DEBUG
if let text = message as? String {
print("\(function): \(text)")
}
#endif
}
Это может быть удобно, когда вам нужно сделать что-то вроде этого:
DLog("Received data:")
DLog(NSString(data:httpResponseBodyData, encoding:NSUTF8StringEncoding))
Ответ 6
Я согласен с ответом uclagamer, который, по сути, является функцией печати с закрытыми окнами, завернутой в препроцессор условным:
func gLog<T>(@autoclosure object: () -> 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("gLog only works for values that conform to CustomDebugStringConvertible or CustomStringConvertible")
}
let fileURL = NSURL(string: file)?.lastPathComponent ?? "Unknown file"
let queue = NSThread.isMainThread() ? "UI" : "BG"
let gFormatter = NSDateFormatter()
gFormatter.dateFormat = "HH:mm:ss:SSS"
let timestamp = gFormatter.stringFromDate(NSDate())
print("\(timestamp) \(queue) = \(fileURL) | \(function)[\(line)]: " + stringRepresentation)
#endif
}
Это обновление для Swift 2.0. Весь кредит принадлежит Abider Nasir. Его оригинальное сообщение в блоге (и связанное значение) можно найти здесь:
http://abizern.org/2015/02/01/debug-logging-in-swift/
ВАЖНОЕ ЗАМЕЧАНИЕ: если кто-то пытается найти раздел "Быстрые компиляторы - пользовательские флаги в настройках сборки", о котором упоминалось много раз, вам нужно убедиться, что показаны настройки "Все", а не только "Основные" параметры сборки, как и по умолчанию.
![введите описание изображения здесь]()
Ответ 7
Чистая магия _isDebugAssertConfiguration()
делает все, а не Custom Flags
-связанный беспорядок:
func log<T>(argument: T, file: String = #file, line: Int = #line, function: String = #function) {
guard _isDebugAssertConfiguration() else {
return
}
let fileName = NSURL(fileURLWithPath: file, isDirectory: false).URLByDeletingPathExtension?.lastPathComponent ?? "Unknown"
print("\(fileName)@\(line)/\(function): \(argument)")
}
Подробнее об этом (и опциях): fooobar.com/info/14633/....