在Swift项目中禁用NSLog进行生产

时间:2014-11-12 15:27:54

标签: ios objective-c swift

所以这个答案Do I need to disable NSLog before release Application?提供了一个在生产环境中禁用NSLog的好方法,但不幸的是,这个解决方案似乎不适用于Swift项目。我的方法是将以下代码放在我用于项目中某些pod的桥接头.h文件中。

#ifdef DEBUG
    #define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
    #define DLog(...) do { } while (0)
#endif

但是,在Swift代码中使用DLog会导致编译器声明它们是未识别的符号。是否有其他地方我应该放置这个#ifdef或者是否有一个不同的Swift项目解决方案?

8 个答案:

答案 0 :(得分:41)

您需要设置编译器标志以使用Swift预处理器 - 转到Build Settings的 Swift编译器 - 自定义标志部分以设置-D DEBUG标志:< / p>

DEBUG flag

然后在您的代码中,您可以定义DLog()函数,并仅在设置DEBUG标志时打印您的消息:

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

答案 1 :(得分:8)

我是一名非常初级的开发人员,需要更清楚地定义一些内容,以便随时跟进。我一直遇到类似问题的困难,取而代之的是println(),当我问这个问题时,我的查询被标记为这个问题的副本。

经过大量研究,试验,错误,错误,错误和错误!!后,我发现我需要遵循的顺序是:

  1. 单击Xco​​de项目窗口左侧File Navigator顶部的项目名称。这是具有项目名称,有多少构建目标以及iOS SDK版本的行。
  2. 选择构建设置标签,然后向下滚动到&#34; Swift编译器 - 自定义标志&#34;底部附近。单击其他标志旁边的向下箭头以展开该部分。
  3. 点击调试行将其选中。将鼠标光标放在该行的右侧,然后双击。将出现一个列表视图。点击列表视图左下角的 + 按钮添加值。文本字段将变为活动状态。
  4. 在文本字段中,输入文字-D DEBUG,然后按返回以提交该行。
  5. 将新的Swift文件添加到项目中。您将要为该文件创建自定义类,因此请按以下行输入文本:

    class Log {
    
       var intFor : Int
    
      init() {
        intFor = 42
      }
    
      func DLog(message: String, function: String = __FUNCTION__) {
        #if DEBUG
          println("\(function): \(message)")
        #endif
      }
    }
    
  6. (我今天很难让类init被Xcode接受,所以init可能比必要的重量级更重。)

    1. 现在,您需要在任何打算使用新自定义函数的类中引用您的自定义类来代替println()在每个适用的类中将其添加为属性:

         let logFor = Log()
      
    2. 现在,您可以将println()的所有实例替换为logFor.DLog()。输出还包括调用该行的函数的名称。

    3. 请注意,在类函数内部我无法调用该函数,除非我将该函数的副本作为该类中的类函数,并且println()对输入也更灵活一些,所以我无法在我的代码中的每个实例中使用它。

答案 2 :(得分:6)

查看关于撰写断言here

的Apple Swift博客文章

简而言之,答案是将DLog编写为:

func DLog(message:String, function:String = __FUNCTION__) {
#if !NDEBUG
    NSLog("%@, %@", function, message)
#endif
}

答案 3 :(得分:1)

下面,我修改了上面给出的Nate Cook的答案。此版本适用于StringNSString个参数:

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))

答案 4 :(得分:1)

#if DEBUG
#else
public func NSLog(_ format: String, _ args: CVarArg...)
{
    // noop
}
#endif

导致此问题的任务:swift debugPrint vs print

答案 5 :(得分:0)

我刚刚发现了这个惊人的全局功能: https://gist.github.com/Abizern/a81f31a75e1ad98ff80d

这符合Nate Cook的答案,并且还会打印遇到的调试打印声明的文件名和行号。

答案 6 :(得分:0)

我同意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/

重要说明:如果有人在努力寻找“Swift编译器 - 构建设置的自定义标志”部分,这已被提及很多次,您需要确保显示“所有”构建设置,而不仅仅是“基本”构建设置,默认情况下。

enter image description here

答案 7 :(得分:0)

纯魔法_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)")
}

在此处查看有关它的更多信息(和选项):https://stackoverflow.com/a/34532569/496389