如何调试iOS扩展(.appex)?

问题描述 投票:0回答:5

如何使扩展中的日志打印出现在 Xcode 的 lldb 调试器中?

ios xcode swift lldb ios8-share-extension
5个回答
50
投票

简单回答:

  • 日志消息不会打印,但是您可以在断点处停止,然后使用 lldb打印所有内容。
  1. 运行您的应用程序
  2. 应用程序运行时,转到 调试 -> 按 PID 或名称附加到进程

enter image description here

  1. 写下您的扩展名(因为bundle-id不起作用!?),然后单击“附加”。

enter image description here

  1. 然后使用您可以在设备上执行此操作的任何方式运行您的扩展。
  2. 等待 Xcode 的调试器在断点处停止扩展,但有些可能需要调用
    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;
}

12
投票

您不需要像这样手动附加到您的应用程序扩展。 Xcode 应该自动处理这一切。

查看运行方案编辑器以了解您的扩展方案。 可执行文件将设置为您的应用程序,或设置为“启动时询问”。 无论哪种情况,运行扩展目标最终都会启动您选择的应用程序。

转到设备上的该应用程序,创建/选择应用程序中要共享的任何内容,单击共享图标,在活动共享扩展程序列表中选择您的扩展程序。 然后,当您的共享扩展启动时,调试器将自动附加到它。 这可能需要几秒钟,但您会看到您的扩展及其所有线程都显示在调试导航器中,如果您设置任何断点,它应该在这些断点处停止。

如果您这样做,调试器还将连接到标准输出,以便您可以在调试器控制台中看到日志消息。


0
投票

如果您正在设备上进行调试,您可以使用 Command、Shift、2 打开设备管理器并查看其中的控制台消息。选择您的设备。

如果您在模拟器上进行调试,这些消息将记录到系统日志中。您可以使用 Command / 或模拟器调试菜单中的“打开系统日志”从模拟器中打开它。


0
投票

自 Xcode 14 起:

  1. 选择菜单命令“窗口”>“设备和模拟器”。
  2. 选择 iOS 设备
  3. 按查看设备日志按钮查看崩溃日志,或打开控制台查看其他日志。

0
投票

根据我的经验,当调试器失败时,获取日志的最简单方法是使用带有自定义类别+控制台的记录器。示例:

import os

class MyViewController: UIViewController {
    
    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "MyAmazingLogger")
        override func viewDidLoad() {
            logger.error("MyViewController viewDidLoad")
        }
    }

}   

之后打开您的控制台应用程序,过滤您的类别的输出并继续您的生活

© www.soinside.com 2019 - 2024. All rights reserved.