Видаліть println () для версії iOS Swift


84

Я хотів би глобально ігнорувати всі println()дзвінки у моєму коді Swift, якщо я не буду у збірці налагодження. Я не можу знайти жодної надійної покрокової інструкції для цього, і буду вдячний за вказівки. є спосіб зробити це глобально, або мені потрібно зробити , щоб оточувати кожен println()з #IF DEBUG/#ENDIFтвердженнями?



6
друк більше не виводиться в консолі пристрою, а в консолі налагоджувача .. Тому немає необхідності видаляти для випуску версії.
Аніш Парадзюлі,

1
Станом на Xcode 8 та swift 3, я не бачу відбитків у консолі у режимі випуску.
CiNN

Відповіді:


101

Найпростіший спосіб - поставити власну глобальну функцію перед Swift println:

func println(object: Any) {
    Swift.println(object)
}

Коли настав час зупинити реєстрацію, просто прокоментуйте тіло цієї функції:

func println(object: Any) {
    // Swift.println(object)
}

Або ви можете зробити це автоматичним, використовуючи умовний:

func println(object: Any) {
    #if DEBUG
        Swift.println(object)
    #endif
}

EDIT У Swift 2.0 printlnзмінено на print. На жаль, зараз він має варіативний перший параметр; це круто, але це означає, що ви не можете легко це перевизначити, оскільки Swift не має оператора "splat", тому ви не можете передавати варіатичний код (його можна створити лише буквально). Але ви можете зробити зменшену версію, яка працює, якщо, як це зазвичай буває, ви друкуєте лише одне значення:

func print(items: Any..., separator: String = " ", terminator: String = "\n") {
    Swift.print(items[0], separator:separator, terminator: terminator)
}

У Swift 3 вам потрібно придушити зовнішню мітку першого параметра:

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    Swift.print(items[0], separator:separator, terminator: terminator)
}

3
Гарне рішення, дякую. Мені сказали, що в iOS (але не в OS X) println()не виконується в режимі випуску.
Nate Birkholz

13
@NateBirkholz Ні, це нісенітниця. (Сказав, що після тестування, щоб переконатися!)
Метт

У Swift 2, із перейменованою функцією для друку, чи просто б ви нагодили функцію збігатися? Крім того, як би ви визначили це глобально? Я спробував розмістити його поза своїм класом в AppDelegate, і він просто ніколи не викликається, хоча у мене є мільйон викликів print (). Ось що я спробував: func print (object: Any) {Swift.print (object)}
Чарлі

@Charlie Так, я все ще використовую його зі printlnзміненим на print. Причина, по якій це не працює для вас, полягає в тому, що ваше printвизначення не відповідає визначенню Свіфта, тому ви не перевизначаєте його. Існує невелика проблема, оскільки, як вже неодноразово зазначалося, Swift не має оператора splat, тому ви не можете пройти варіадику. Але він чудово працює для одного елемента, який ви можете передати як items[0].
matt

2
Одне застереження, якщо ви вставляєте ці оператори журналу в високоефективні розділи коду: Swift все одно витратить час, виконуючи інтерполяцію рядків та параметри візуалізації для передачі функції, навіть якщо вони не будуть використовуватися. Єдиний спосіб, яким я бачу насправді умовно видалити твердження, - це передбачити їх на прапорі. наприклад if (log) {print (..)} у кожному місці, де вони використовуються.
Pat Niemeyer

46

Оновлено для Swift 4.x:

З випуском бета-версії Swift 2.0 / 3.0 та Xcode 7/8 було внесено деякі зміни у спосіб вимкнення функції друку у збірках випусків.

Є кілька важливих моментів, згаданих вище @matt та @Nate Birkholz, які досі є дійсними.

  1. println()Функція була заміненаprint()

  2. Щоб використовувати #if DEBUG макрос, вам слід визначити "Swift Compiler - Спеціальні прапори - Інші прапори", щоб містити значення-D DEBUG

  3. Я б порекомендував замінити Swift.print()функцію в глобальній області, щоб ви могли використовувати print()функцію як звичайно у своєму коді, але вона видалить вихідні дані для збірок без налагодження. Ось підпис функції, який ви можете додати в глобальній області для цього в Swift 2.0 / 3.0:

    func print(items: Any..., separator: String = " ", terminator: String = "\n") {
    
        #if DEBUG
    
        var idx = items.startIndex
        let endIdx = items.endIndex
    
        repeat {
            Swift.print(items[idx], separator: separator, terminator: idx == (endIdx - 1) ? terminator : separator)
            idx += 1
        }
        while idx < endIdx
    
        #endif
    }
    

Примітка: Ми встановили роздільник за замовчуванням як пробіл, а термінатор за замовчуванням - новий рядок. Ви можете налаштувати це по-різному у своєму проекті, якщо хочете.

Сподіваюся, це допомагає.

Оновлення:

Зазвичай переважно цю функцію поставити в глобальному масштабі, щоб вона сиділа перед Свіфтом print функцією . Я вважаю, що найкращий спосіб організувати це - додати файл утиліти до вашого проекту (наприклад, DebugOptions.Swift), де ви можете розмістити цю функцію в глобальному масштабі.

Станом на Swift 3 ++оператор буде застарілим. Я оновив фрагмент вище, щоб відобразити цю зміну.


1
Вибачте, але куди поставити функцію?
DàChún,

@ User9527 Навряд чи ви хочете помістити це десь у глобальному масштабі, щоб воно було доступним протягом усього проекту. У своїх проектах я додаю швидкий файл утиліти (DebugOptions.swift або щось подібне) і розміщую цю функцію в глобальній області (тобто не в закритому класі).
Главід

Чи можете ви підтвердити, що станом на поточну версію Swift-Xcode, оператор друку більше не буде виводитися на консоль пристрою без необхідності встановлювати -D налагодження рівним? Принаймні це те, що я перевірив сьогодні.
user523234

1
Починаючи з Swift 3, можна отримати трохи більше стислості, додавши підкреслення на початку списку аргументів: "print (_ items ..."
Джонатан Чжан

7
Тож я шукав посилання на друк (використовується у didFinishLaunching ...), і це вказало мені на оригінальну функцію друку Swift. Склавши це та коментар @ JonathanZhan разом, я відрегулював функцію так, щоб вона виглядала так, і вона працює:public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Джонні

38

Проблема всіх цих підходів, включаючи мій, полягає в тому, що вони не знімають накладних витрат на оцінку printаргументів. Незалежно від того, який із них ви використовуєте, це буде дорого:

print(myExpensiveFunction())

Єдиним гідним рішенням є обернення фактичного виклику друку в умовній компіляції (припустимо, що DEBUGце визначено лише для збірки налагодження):

#if DEBUG
print(myExpensiveFunction())
#endif

Це, і лише це, заважає myExpensiveFunctionвикликатися у збірці випуску.

Однак ви можете відсунути оцінку на один рівень за допомогою автоматичного закриття . Таким чином, ви можете переписати моє рішення (це Swift 3) так:

func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    Swift.print(item(), separator: separator, terminator: terminator)
    #endif
}

Це вирішує проблему лише у тому випадку, коли ви друкуєте лише одне, що, як правило, відповідає дійсності. Це тому item(), що не викликається в режимі звільнення.print(myExpensiveFunction())таким чином перестає бути дорогим, тому що дзвінок загортається в закриття без оцінки, а в режимі звільнення він взагалі не оцінюється.


Яка користь @autoclosure?
kelin

@matt у своїй книзі ви згадуєте "Важливою особливістю друку є те, що він ефективно припиняється, коли додаток запускається незалежно від Xcode", чи означає це, що ми можемо залишати свої заяви про друк у поданих нами програмах сьогодні, або я не розумію щось?
приховане ім'я користувача

@ hidden-username Так, я, як правило, залишаю свої printвиписки в коді доставки, але це відрізняється від того, що стосується моєї відповіді. printОператор висновку не відправляється на консоль в вашому Xcode-незалежної збірки релізу, але вона по - , як і раніше оцінюється , так що залишається корисно знати , як придушити цю оцінку тільки в разі , якщо це дорого чи має небажані побічні ефекти.
matt

@matt, добре ... Так, я неправильно зрозумів це. Я їх прокоментую. Дякую
приховане ім'я користувача

Чи буде такий підхід видалити надрукований рядок із двійкового файлу? Наприклад, якщо я використовував цей метод і десь у своєму додатку я ставлю "print (" користувач увійшов у систему ")", а потім, якщо хтось спробує здійснити зворотне проектування мого додатка, чи знайде він десь цей рядок, чи його взагалі не буде?
Лешек Шарі

18

Як уже зазначалося, я студент і потребую речей, визначених трохи чіткіше, щоб слідувати. Після багатьох досліджень послідовність, яку мені потрібно було дотримуватися, така:

Клацніть на назву проекту у верхній частині навігатора файлів ліворуч від вікна проекту Xcode. Це рядок із назвою проекту, кількістю цілей збірки та версією iOS SDK.

Виберіть вкладку " Параметри побудови" та прокрутіть униз до розділу " Швидкий компілятор - Спеціальні прапори " внизу. Клацніть стрілку вниз поруч із пунктом Інші прапори із пунктом щоб розгорнути розділ.

Клацніть на рядку Налагодження, щоб вибрати його. Наведіть курсор миші на праву сторону рядка та двічі клацніть. З'явиться вікно списку. Клацніть на + внизу ліворуч від подання списку, щоб додати значення. Текстове поле стане активним.

У текстове поле введіть текст -D DEBUGі натисніть Return щоб зафіксувати рядок.

Додайте новий файл Swift до свого проекту. Ви хочете створити власний клас для файлу, тому введіть текст у рядках, наведених нижче:

class Log {

  var intFor : Int

  init() {
    intFor = 42
   }

  func DLog(message: String, function: String = __FUNCTION__) {
    #if DEBUG
      println("\(function): \(message)")
    #endif
  }
}

У мене були проблеми з тим, щоб сьогодні клас прийняв Xcode, тому init може бути трохи важчим, ніж потрібно.

Тепер вам потрібно буде посилатися на власний клас у будь-якому класі, в якому ви збираєтесь використовувати нову спеціальну функцію замість println()Add this як властивість у кожному застосовному класі:

   let logFor = Log()

Тепер ви можете замінити всі екземпляри println()з logFor.DLog(). Вихідні дані також включають ім'я функції, в якій був викликаний рядок.

Зверніть увагу, що всередині функцій класу я не міг викликати функцію, якщо не зробив копію функції як функції класу в цьому класі, а println()також трохи гнучкіший із введенням, тому я не міг використовувати це в кожному випадку в мій код.


8
Немає необхідності створювати власний клас для журналу налагодження. Простіше і практичніше використовувати глобальну функцію.
Войтех Врбка

Яка користь від intFor = 42?
Тед

15

Стрімкий 5

Просто створіть новий файл у своєму проекті та вставте цей код у:

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    items.forEach {
        Swift.print($0, separator: separator, terminator: terminator)        
    }
    #endif
}

Цей підпис функції відповідає типовому Swift, тому він "перезаписує" функцію у вашому проекті. За потреби ви все ще можете отримати доступ до оригіналу за допомогою Swift.print().

Після того, як ви додали код вище, продовжуйте використовувати print()як зазвичай, і він буде друкуватися лише у збірках налагодження.

Примітка. Виконуючи forEachдрук кожного елемента, можна позбутися надокучливих дужок масиву навколо операторів друку, які з’являються, якщо ви просто переходите itemsпрямо доSwift.print() .

Для тих, хто відносно новачок у Свіфті, ви можете задатися питанням, що за біс $0. Він просто представляє перший аргумент, переданий в forEachблок. forEachЗаява також може бути записане таким чином:

items.forEach { item in
    Swift.print(item, separator: separator, terminator: terminator)        
}

Нарешті, якщо вам цікаво, декларація Swift printвиглядає так:

public func print(_ items: Any..., separator: String = " ", terminator: String = "\n")

Моя відповідь вище відображає точну реалізацію Swift - хоча я ніколи не друкую більше, ніж одну річ, або змінюю роздільник / термінатор. Але хто знає, ви можете захотіти.


2
де оголосити цю функцію, це якесь розширення чи щось подібне? Я просто не хочу заявляти це у кожному файлі)
Матросов Олександр

1
@MatrosovAlexander Ви можете просто створити швидкий файл у будь-якому місці проекту проекту та вставити цей код. Компілятор достатньо розумний, щоб зробити його глобально доступним.
Trev14,

11

Ось я використовую функцію, яка чудово працює в Swift 3:

func gLog<T>( _ object: @autoclosure() -> 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 = Thread.isMainThread ? "UI" : "BG"
    let gFormatter = DateFormatter()
    gFormatter.dateFormat = "HH:mm:ss:SSS"
        let timestamp = gFormatter.string(from: Date())

        print("✅ \(timestamp) {\(queue)} \(fileURL) > \(function)[\(line)]: " + stringRepresentation + "\n")
    #endif
    }

Ось приклад результату, який він генерує:

скріншот виводу

Пояснення:

  • зелена галочка використовується для швидкого перегляду повідомлень для друку (gLog) у консолі, де вони іноді можуть загубитися в морі інших повідомлень

  • штамп часу / дати

  • потік, на якому він запущений - у моєму випадку це або MainThread (який я називаю UI), або не MainThread (який я називаю BG, для фонового потоку)

  • ім'я файлу, в якому знаходиться повідомлення gLog

  • функція у файлі, в якому знаходиться повідомлення gLog

  • номер рядка повідомлення gLog

  • фактичне повідомлення gLog, яке ви хочете роздрукувати

Сподіваюся, це корисно комусь іншому!


це можна помістити в окремий файл, який буде використовуватися у всій програмі? Я спробував помістити його в окремий файл класу як метод класу. Але він аварійно завершує роботу з libMobileGestalt MobileGestaltSupport.m: 153: pid 2574 (Демо) не має доступу в пісочниці для frZQaeyWLUvLjeuEK43hmg і НЕ має належного права libMobileGestalt MobileGestalt.c: 550: немає доступу до InverseDevicear5 (див. <R / 117) ) Повідомлення від налагоджувача: Припинено через проблему з пам'яттю
omarojo

omarojo, я використовую це як глобальну функцію у всьому своєму додатку. Жоден клас не потрібен. У мене є файл із назвою utils.swift, який містить усі мої утиліти, такі як ця. Вам просто потрібно переконатися, що імпортуєте Foundation - можливо, це крок, який ви пропустили? До речі, для отримання більш докладної інформації про декларування своїх функцій всередині класів, як статичні функції всередині класів, або як глобальні функції, см це так питання і відповіді: stackoverflow.com/questions/30197548 / ...
Джин Loparco

Так, він запрацював, просто створивши новий файл із функцією всередині. З якоїсь причини її використання як функції класу призведе до збою програми без чіткого повідомлення про налагодження.
omarojo

Дякую за цього чоловіка, сором, я не знайшов цього раніше. Врятував мені багато головного болю налагодження.
beowulf

З задоволенням @beowulf!
Gene Loparco

9

Тестується за допомогою Swift 2.1 та Xcode 7.1.1

Існує простий спосіб виключити всі оператори друку з версій випуску, як тільки ви дізнаєтесь, що порожні функції видаляє компілятор Swift .

Побічна примітка: В епоху Objective-C існував попередній синтаксичний аналізатор, який можна було використовувати для видалення операторів NSLog до того, як компілятор запуститься, як описано в моїй відповіді тут . Але оскільки Swift більше не має попереднього аналізатора, цей підхід більше не діє.

Ось те, що я сьогодні використовую як вдосконалену та легко конфігурувану функцію журналу, і ніколи не турбуватися про її видалення у збірках випусків. Також, встановивши різні прапори компілятора, ви можете налаштувати інформацію, яка реєструється, за необхідності.

Ви можете налаштувати функцію за потреби, будь-яка пропозиція щодо її вдосконалення вітається!

// Gobal log() function
//
// note that empty functions are removed by the Swift compiler -> use #if $endif to enclose all the code inside the log()
// these log() statements therefore do not need to be removed in the release build !
//
// to enable logging
//
// Project -> Build Settings -> Swift Compiler - Custom flags -> Other Swift flags -> Debug
// add one of these 3 possible combinations :
//
//      -D kLOG_ENABLE
//      -D kLOG_ENABLE -D kLOG_DETAILS
//      -D kLOG_ENABLE -D kLOG_DETAILS -D kLOG_THREADS
//
// you can just call log() anywhere in the code, or add a message like log("hello")
//
func log(message: String = "", filePath: String = #file, line: Int = #line, function: String = #function) {
            #if kLOG_ENABLE

            #if kLOG_DETAILS

            var threadName = ""
            #if kLOG_THREADS
                threadName = NSThread.currentThread().isMainThread ? "MAIN THREAD" : (NSThread.currentThread().name ?? "UNKNOWN THREAD")
                threadName = "[" + threadName + "] "
            #endif

            let fileName = NSURL(fileURLWithPath: filePath).URLByDeletingPathExtension?.lastPathComponent ?? "???"

            var msg = ""
            if message != "" {
                msg = " - \(message)"
            }

            NSLog("-- " + threadName + fileName + "(\(line))" + " -> " + function + msg)
        #else
            NSLog(message)
        #endif
    #endif
}

Ось де ви встановлюєте прапори компілятора:

введіть тут опис зображення

Приклад виводу з усіма прапорами на виглядає так:

   2016-01-13 23:48:38.026 FoodTracker[48735:4147607] -- [MAIN THREAD] ViewController(19) -> viewDidLoad() - hello

Код з log () виглядає так:

    override func viewDidLoad() { log("hello")
    super.viewDidLoad()

   // Handle the text field's user input through delegate callbacks
   nameTextField.delegate = self
}

Хороший! Я взяв його звідси і зрештою зробив AELog та AEConsole .
tadija

Це нормально працює в режимі DEBUG. Тепер я змінив режим ВИПУСКУ з Редагування схеми. Він також відображає вікно входу в консоль для режиму звільнення. Чому так?
Jayprakash Dubey

Для Swift 3.2 у Xcode 9 мені потрібно було змінити NSLog для друку та виклику за допомогою журналу (повідомлення: "привіт"), також мені довелося поставити прапори як "-D" "kLOG_ENABLE", із лапками. Усі інші швидкі оновлення версії були підібрані компілятором із запропонованими виправленнями.
iCyberPaul

1
Тут ви вказуєте "порожні функції видаляються компілятором Swift", де в документації ми це знаходимо? Звідки ви знаєте, що це так? @ ronny-webers
zumzum

7

Ще простіше, переконавшись -D DEBUG, що встановлено OTHER_SWIFT_FLAGSпараметри збірки налагодження:

#if !DEBUG
    func print(_ items: Any..., separator: String = " ", terminator: String = "\n") { }
#endif

Я підозрюю, що для цього може знадобитися "де", оскільки об'єкти для друку відповідають одному з тих системних протоколів, про які ви рідко згадуєте у vids для wwdc, і я думаю, що в кінці швидких посібників (1,2) проти 2, забули різницю, якщо там є єдиним із системним
Стівен Дж.

Поки це працює з Swift 1.2. Не пробував 2.0.
Рівера,

6

XCode 8 представив кілька нових налаштувань збірки .
Зокрема, згаданий Active Compilation Conditionsробить подібним чином, як це робили налаштування інших прапорів .

"Активні умови компіляції" - це новий параметр збірки для передачі прапорців умовної компіляції компілятору Swift.

Відповідно до XCode 8 (протестовано в 8.3.2) ви отримаєте це за замовчуванням:

введіть тут опис зображення

Тож без будь-якого конфігура ви можете написати наступне:

#if DEBUG
    print("⚠️ Something weird happened")
#endif

Я настійно рекомендую вам, якщо ви широко використовуєте цей підхід, створити клас / структуру / функцію, яка обгортає цю логіку ведення журналу. Можливо, ви захочете продовжити це далі по дорозі.


4

Наразі Варун Нахарія має найкраще рішення. Я б поєднав його відповідь з відповіддю Рівери ...

  1. створити -D DEBUGпрапор на директивах компілятора, побудувати налаштування.
  2. потім додайте цей код:

    #if !DEBUG
     public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    }
    #endif
    

Цей код перетворить усі printна ніщо для випуску.


3

Swift 4 Xcode 10.0

можливо, ти міг би цим скористатися

func dPrint(_ message: @autoclosure () -> Any) {
    #if DEBUG
    print(message())
    #endif
}

Причиною використання @autoclosureє те, що якщо ви передаєте функцію як параметр повідомлення, функція буде викликана лише в режимі налагодження, це призведе до удару продуктивності.

на відміну від Swift.print(_ items: Any..., separator: String = default, terminator: String = default)функції, моє рішення має лише один параметр, оскільки в більшості випадків ми не передаємо декілька параметрів, оскільки функція друку відображає інформацію лише в консолі, ми можемо просто перетворити параметри в String: "\(param1)"+"\(param2)"так? сподіваюся, вам подобається моє рішення


1

Ви також можете використовувати точку зупинки, налаштувати її на продовження після оцінки та написати повідомлення про друк у точці зупинки!

введіть тут опис зображення


0

Ви можете визначити, debug_printlnчий вміст буде приблизно:

#if DEBUG
  println()
#endif

Дякую, де мені найкраще це визначити? Я студент, боюся, і дуже ціную допомогу, але вимагаю більш чіткого контексту.
Nate Birkholz

Ви задекларуєте це у файлі заголовка, який ви імпортуєте туди, де хочете його використовувати.
Ian MacDonald

0

Моє рішення - використовувати цей код в AppDelegate перед класом

// Disable console log in live app
#if !arch(x86_64) && !arch(i386)
    public func debugPrint(items: Any..., separator: String = " ", terminator: String = "\n") {

    }
    public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {

    }
#endif

class AppDelegate: UIResponder, UIApplicationDelegate {
// App Delegate Code 

}

0

для мого рішення я роблю це просто

import UIKit

class DLog: NSObject {

   init(title:String, log:Any) {
       #if DEBUG
           print(title, log)
       #endif

   }

}

то щоб показати це просто зателефонуйте

_ = DLog(title:"any title", log:Any)

0

У підсумку я використав це:

#if DEBUG
func dLog(_ item: @autoclosure () -> Any, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
    print("\(Date()) [\((file as NSString).lastPathComponent):\(line) \(function)] \(item())")
}
#else
func dLog(_ item: @autoclosure () -> Any) {}
#endif

Він досить компактний, друкує корисну інформацію (відмітку часу, швидке ім'я файлу, рядок коду, ім'я функції), і принаймні в моїх тестах я не міг знайти жодних записаних рядків у двійковому файлі програми, коли його відкривали в hex editior.


0

Ще простіше: скористайтеся тим, що твердження видаляються із збірок випусків і лише звідти викликають друк. Це видаляє всі журнальні виклики (так, навіть дзвінки до Log.da), оскільки вони є порожніми під час створення для випуску.

Але я також чув, що відбитки видаляються для збірки випусків, але не міг знайти його письмово. Отже, зараз я використовую щось подібне Logнижче. У мене є більш м'яка версія на GitHub із смайликами (для читабельності) та темами журналу (для узгодженості):

https://github.com/Gatada/JBits/blob/master/Project/Utility/Log.swift

public enum Log {

    /// A date formatter used to create the timestamp in the log.
    ///
    /// This formatter is only created if it is actually used, reducing the
    /// overhead to zero.
    static var formatter: DateFormatter?

    // MARK: - API

    /// Call to print message in debug area.
    ///
    /// Asserts are removed in release builds, which make
    /// the function body empty, which caused all calls to
    /// be removed as well.
    ///
    /// Result is zero overhead for release builds.
    public static func da(_ message: String) {
        assert(debugAreaPrint(message))
    }

    // MARK: - Helpers

    /// The function that actually does the printing. It returns `true` to
    /// prevent the assert from kicking in on debug builds.
    private static func debugAreaPrint(_ message: String) -> Bool {
        print("\(timestamp) - \(message)")
        return true
    }

    /// Creates a timestamp used as part of the temporary logging in the debug area.
    static private var timestamp: String {

        if formatter == nil {
            formatter = DateFormatter()
            formatter!.dateFormat = "HH:mm:ss.SSS"
        }

        let date = Date()
        return formatter!.string(from: date)
    }
}

У коді:

Log.da("This is only handled in a debug build.")

Бачиться в області налагодження Xcode лише під час запуску збірки налагодження:

13: 36: 15.047 - Це обробляється лише у збірці налагодження.


0

Мій проект був розроблений в Objective C, але з минулого року я розпочав злиття нового коду в Swift, отже, в Swift рішення нижче працювало для мене, я додав цей код у константний файл My Swift:

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    items.forEach {
        Swift.print($0, separator: separator, terminator: terminator)
    }
    #endif
}

0

Це працює для мене (додайте це як глобальну функцію в проекті)

func print(_ items: Any...) {
    #if DEBUG
        Swift.print(items[0])
    #endif
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.