Отключение 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 может быть немного тяжелее, чем необходимо.)

  1. Теперь вам нужно будет ссылаться на свой пользовательский класс в любом классе, в котором вы намерены использовать новую настраиваемую функцию вместо println() Добавить это как свойство в каждом применимом классе:

       let logFor = Log()
    
  2. Теперь вы можете заменить любые экземпляры println() на logFor.DLog(). Вывод также включает имя функции, в которой была вызвана строка.

  3. Обратите внимание, что внутри функций класса я не мог вызывать функцию, если только я не сделал копию функции как функцию класса в этом классе, а 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/....