正确地启用 Logging 机制

来源:互联网 发布:mac版qq怎么远程控制 编辑:程序博客网 时间:2024/05/20 12:25

简单的说,在开发过程中,我们可以用 NSLog 肆无忌惮地向终端输出各种信息,但是正式版本可不能这样了,不然用户手机的 Console 会被你的 Log 塞满,不仅影响性能,可能还会暴露不必要的一些开发信息。

那么,如何在 Swift 项目里正确地设置 Logging 呢?以下我以 Crashlytics 为例,当然,用其他工具甚至不用第三方工具也是可以的。

在过去 Objective-C 项目里,针对 Development 环境和 Release 环境使用不同的方法进行 Logging 我们是通过 Preprocessor Macros 来进行的。比如 DEBUG 是作为一个默认的 Macro 加进去的:看下图,只要有 $(inherited) 这个在,DEBUG 这个 Macro 就会存在项目的 Development 模式。

那么在 Swift 项目里面我们如何去区分 Debug 和 Release 模式呢?自然也有类似的方式。

实际上,Swift 语言也支持类似于 C 语言一样的 Macro,常用的那些基本能满足我们的使用需求。使在 Swift 项目里也和 Objective-C 一样使用 DEBUG 来区分 Debug 和 Release,我们只需要到 Target 的 Build Settings 里面,找到 Swift Compiler Custom Flags,在 Debug 处传入一个 -D DEBUG 即可。

这样如果你的项目混合了 Objective-C 和 Swift,Objective-C 代码依然会通过之前的 DEBUG 来做正确的分支编译,Swift 编译器也可以通过这个专门的 Custom Flags 来作分支编译。

定义好了这个,我们就可以做正确的 Logging 处理了。

在 AppDelegate.swift (或其他),我做了如下的定义:

import Crashlyticsfunc NSLog(format: String, args: CVarArgType...) {    #if DEBUG        CLSNSLogv(format, getVaList([]))    #else        CLSLogv(format, getVaList([]))    #endif}

主要说明:

  • CLSNSLogv 是 Crashlytics 提供的,既向终端输出 Log,也会包含在 Crash Log 里面的方法,适合开发用;
  • CLSLogv 则是不会向终端输出 Log,但会包含在 Crash log 里的方法,适合 Release 版本用。

于是我在 Swift 代码里重写了 NSLog 这个方法,使其根据不同的编译环境使用不同的 Crashlytics 方法,达到了我预期的效果。

这里还有一点可以改进或讨论的余地,由于 Swift 把 String 的使用变得很方便,我从环境变量构建一个字串再也不用像 Objective-C 那样:

NSLog(@"Hello, this is %@, I'm %d", name, age")

而是直接使用灵巧的 Swift 方式:

NSLog("Hello, this is \(name), I'm \(age)")

因而我用不着 args 部分,只通过 getVaList([]) 传一个空的参数列表进去即可。在实际的使用过程中,这个新包装的 NSLog 也永远也不需要去用到参数列表部分,直接用 Swift 的方式即可。

根据上图,由于我当前是 DEBUG 环境,Xcode 直接高亮了 #if DEBUG 那一块,方便我识别。这样,开发环境中我就可以在终端里看到 Log 输出,而在正式发布的时候它们就不会输出来。我可以像以前一样在项目的其他地方继续用 NSLog,所更改的地方也就是这么一个设置+短短的几行就完成了。

除了因为混合 Objective-C 和 Swift 环境的情况下,我们需要分别设置和确认 Macro/Flag 有没有被设置这点琐碎外,其他我用的还是蛮愉快的。


0 0