Any tricks to use QuickLook debugging on a struct (or enum)?

So Xcode has a handy "quick look" feature, it can visualize NSBezierPaths, UIImages, NSAttributedStrings and a bunch more Apple supplied classes. It will also visualize anything you have an @objc debugQuickLookObject() -> AnyObject (and AnyObject needs to be one of like a dozen+ things when you return it)...but you can only add that to a class, not a struct or enum (or I'm missing a trick!)

So far my not-very convent workaround is to have a method with a short name and then manually "add expression" to the local variables view and then get a QL on the expression. It is less then convenient, but does work.

Does anyone have suggestions on how to more directly get a quicklook either from the lldb command prompt, or to make Xcode recognize the "quicklookness" of a value type?

3 Likes

Thanks for asking the question. I'm looking for the answer too and in the meantime the "add expresssion" trick you described helped me a lot.

1 Like

I wish someone from Apple would answer this, but in the meantime you could maybe create an @objc wrapper class just for the purpose of quicklook'ing.

1 Like

Resurrecting this question. Any ways to do this yet with a struct type? I figured you could do what the OP said, then add a synthesized property to the type in a .lldbinit file that adds the method result to the expanded list of properties. That's hard to synchronize across lots of devs, though.

1 Like

I gave it a go and here's an unsatisfactory solution that allows revealing Xcode's quicklook view without adding expression into Xcode's expressions' list. Unfortunately it requires adding quite some boilerplate to the value type in question which makes it barely tolerable.

#if DEBUG
// MARK: this is one off, so, fine
class QuickLookDebugger {
    var proc: (() -> Any?)?
    @objc func debugQuickLookObject() -> Any? {
        proc?()
    }
}
#endif

struct Foo {
    let red, green, blue: CGFloat
    
    #if DEBUG
    // MARK: (1) this bit is ok, same as with classes just w/o @objc:

    func debugQuickLookObject() -> Any? {
        // take struct's value into account
        UIImage(systemName: "person") // or whatever else
    }
    
    // MARK: (2) this bit is tolerable - one extra line:

    var debugObject = QuickLookDebugger()
    
    // MARK: (3) this bit I hate... it's quite a boilerplate,
    // MARK: beside you might've already had an init or a few:

    init(red: CGFloat, green: CGFloat, blue: CGFloat) {
        self.red = red
        self.green = green
        self.blue = blue
        debugObject.proc = debugQuickLookObject
    }
    #endif
}

I don't know a way to pass "self" into a struct's property initializer here to save on "init" boilerplate:

var debugObject = QuickLookDebugger(>>> self <<<)

Tried making that variable lazy, but then it is shown as "nil" in Xcode's debugger.

Worth filing a feature request.