如何使扩展中的日志打印出现在 Xcode 的 lldb 调试器中?
简单回答:
waitForDebugger
(这是一个自定义函数,请参阅下面的逻辑)。public static func isDebuggerAttached() -> Bool {
// Buffer for "sysctl(...)" call's result.
var info = kinfo_proc()
// Counts buffer's size in bytes (like C/C++'s `sizeof`).
var size = MemoryLayout.stride(ofValue: info)
// Tells we want info about own process.
var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
// Call the API (and assert success).
let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0)
assert(junk == 0, "sysctl failed")
// Finally, checks if debugger's flag is present yet.
return (info.kp_proc.p_flag & P_TRACED) != 0
}
@discardableResult
public static func waitForDebugger(_ timeout: Int = 30000) -> Bool {
var now: UInt64 = DispatchTime.now().uptimeNanoseconds
let begin = now
repeat {
if isDebuggerAttached() {
// Wait a little bit longer,
// because early breakpoints may still not work.
Thread.sleep(forTimeInterval: 3.0)
return true
}
Thread.sleep(forTimeInterval: 0.1)
now = DispatchTime.now().uptimeNanoseconds
} while Double(now - begin) / 1000000.0 < Double(timeout);
return false;
}
您不需要像这样手动附加到您的应用程序扩展。 Xcode 应该自动处理这一切。
查看运行方案编辑器以了解您的扩展方案。 可执行文件将设置为您的应用程序,或设置为“启动时询问”。 无论哪种情况,运行扩展目标最终都会启动您选择的应用程序。
转到设备上的该应用程序,创建/选择应用程序中要共享的任何内容,单击共享图标,在活动共享扩展程序列表中选择您的扩展程序。 然后,当您的共享扩展启动时,调试器将自动附加到它。 这可能需要几秒钟,但您会看到您的扩展及其所有线程都显示在调试导航器中,如果您设置任何断点,它应该在这些断点处停止。
如果您这样做,调试器还将连接到标准输出,以便您可以在调试器控制台中看到日志消息。
如果您正在设备上进行调试,您可以使用 Command、Shift、2 打开设备管理器并查看其中的控制台消息。选择您的设备。
如果您在模拟器上进行调试,这些消息将记录到系统日志中。您可以使用 Command / 或模拟器调试菜单中的“打开系统日志”从模拟器中打开它。
自 Xcode 14 起:
根据我的经验,当调试器失败时,获取日志的最简单方法是使用带有自定义类别+控制台的记录器。示例:
import os
class MyViewController: UIViewController {
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "MyAmazingLogger")
override func viewDidLoad() {
logger.error("MyViewController viewDidLoad")
}
}
}
之后打开您的控制台应用程序,过滤您的类别的输出并继续您的生活