40332ca5b2a42ac15a940c69237809bf
WWDC20 10168 - 探索 Swift 中的日志记录

本次 Session 的思维导图:

概括

这个 session 介绍了 Swift 统一 logging API 的最新版本。在这个视频中,你将学会:

  1. 在记录应用中的事件和错误的同时,保持日志信息的隐私性。
  2. 在不牺牲性能的情况下,使用功能强大又提供较好可读性的格式化数据选项。
  3. 收集和处理日志信息,以理解和调试应用中的意外行为。

在实际的开发任务中,我们难免会遇到一些难以复现的 bug。使用 log API 能帮助我们理解及处理这类疑难杂症。我们可以在日志记录的众多线索中理解 bug 产生的原因。

来看新版 log API

我们可以利用 log API 在应用运行时记录下重要的事件。记录下的日志会被操作系统存档,以方便我们之后读取这些日志。由于新版 log API 十分高效,它们可以在应用中广泛地使用,且不会拖慢应用的运行速度。
仅需三步,就能在应用中使用 log API:

// 第一步:导入 os 模块
import os

// 第二步:创建 Logger 的实例
// subsystem 一般为 bundle identifier,以便从众多日志中辨别出:哪些是来自该应用的信息
// category 一般表示应用的某个模块,以便进一步辨别出:是来自该应用哪一模块的信息
let logger = Logger(subsystem: "com.example.Fruta", category: "giftcards")

func beginTask(url: URL, handler: (Data) -> Void) {
    launchTask(with: url) {
       handler($0)
    }

// 第三步:使用 log 函数
    logger.log("Started a task \(taskId)")
}

调用 log 函数与调用 print 函数有点相似,但其实有着本质上的不同。因为转换成字符串会很慢,所以 log 信息不会完全转换为字符串。编译器和 logging library 合作对此进行了高度优化。在这种优化之下,只有当 log 信息真正显示的时候,才会付出将其转换为字符串的成本。

新版 log API 支持众多数据类型

log 函数支持很多数据类型,比如数字类型 IntDouble 、Objective-C 对象及所有遵循 CustomStringConvertible 协议的类型。当在 log 消息中加入非数字类型的数据时,非数字类型的数据默认会被系统编辑,这是为了确保应用在实机运行时,不会泄漏个人信息。

看到这里,你可能在心里发问:那当在模拟器上运行时是怎么样的呢?根据 Apple Developer Forums 上的 回答:在 Xcode console 上显示的 log 信息始终不会被系统编辑,也就是说:如果应用从 Xcode 中启动,即使这条 log 信息是非公开的,在 console 中也会完全显示出来,以便开发者调试。

举个例子,这里是在记录类型为字符串的 accountNumber 变量:

但在输出的 log 信息中,accountNumber 被编辑为 <private>
我们也可以手动控制 log 信息为公开的:

在终端中收集日志信息

我们可以使用命令行来收集 log 信息。先把设备连接至电脑,再在终端中输入以下命令:

使用 log help collect 可以获得该命令行的使用帮助。
在收集完之后,在当前路径下会产生一个以 .logarchive 结尾的文件。我们可以使用系统自带的 Console App 浏览该文件。

当在 Console App 中浏览这个文件时,常常会在搜索栏输入关键词来过滤无关的信息。这里分享一个小技巧:在搜索栏输入关键词,输入完毕后,点击右下角的保存按钮,可以将关键词保存起来。



下次搜索时,直接点击 log1 按钮,就自动填充搜索关键词,这样就可以免于重复输入搜索关键字。

在 Console App 中实时检视日志信息

使用 log collect 命令,我们可以在应用运行结束后,打开日志文件,阅读日志信息。在应用运行时,我们可以在 Xcode console 阅读日志信息。类似地,在应用运行时(无论是在真机上运行还是在模拟器上运行),我们也可以实时地在 Console App 里阅读日志信息!

只要在 Console App 内选中正确的设备即可(注:这里的设备包括真机和模拟器):

但在我自己动手尝试之后发现:即使在 Console App 的 Action 菜单里勾选 Include Debug Messages 选项,在 Xcode 中以模拟器的方式启动应用,Console App 里实时显示的日志信息竟然不包含 debug 等级的信息。然而,在 Xcode 中以真机的方式启动应用,Console App 里实时显示的日志信息却包含了 debug 等级的信息!

这可能是个 bug。我已经在 Apple Developer Forums 提交了 反馈

日志等级

系统提供五种不同的日志记录等级:

  1. Debug level;在 debug 时使用
top Created with Sketch.