Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I improve debug information shown on SwiftData properties marked as _SwiftDataNoType?

My function fetches some SwiftData records and creates others. When I inspect them in the debugger, none of their non-nil properties are shown.

debugger showing _SwiftDataNoType

Is there something I can do to enable it to display actual values for these properties?

like image 572
schwabsauce Avatar asked Jan 22 '26 12:01

schwabsauce


1 Answers

I doubt you can control how the left half of the Xcode debugger displays things.

You can, however, conform the model to CustomReflectable:

@Model
class Foo: CustomReflectable {
    var x: String
    var y: String
    init(x: String, y: String) {
        self.x = x
        self.y = y
    }
    
    // put all the model's properties in the dictionary literal here.
    // you can also write a macro to generate this.
    var customMirror: Mirror {
        Mirror(self, children: [
            "x": x,
            "y": y,
        ])
    }
}

Now, you can select the variable storing your model, and click the "i" button with a circle:

enter image description here

and the contents of your custom mirror will be displayed on the right half.

You can also do po dump(x) in the debugger to achieve the same effect.


Here is a macro that generates this CustomReflectable conformance. You can attach this to your class, in addition to @Model.

// declaration
@attached(extension, conformances: CustomReflectable, names: named(customMirror))
public macro ModelMirror() = #externalMacro(module: "ImplementationModule", type: "ModelMirrorMacro")

// implementation
enum ModelMirrorMacro: ExtensionMacro {
    static func expansion(
        of node: AttributeSyntax,
        attachedTo declaration: some DeclGroupSyntax,
        providingExtensionsOf type: some TypeSyntaxProtocol,
        conformingTo protocols: [TypeSyntax], 
        in context: some MacroExpansionContext
    ) throws -> [ExtensionDeclSyntax] {
        guard let classDecl = declaration.as(ClassDeclSyntax.self) else { return [] }
        let name = classDecl.name
        let propertyNames = classDecl.memberBlock.members.compactMap {
            $0.decl.as(VariableDeclSyntax.self)?.bindings.first?.pattern.as(IdentifierPatternSyntax.self)?.identifier
        }
        let extensionDecl = try ExtensionDeclSyntax("extension \(name): CustomReflectable") {
            let kvp = DictionaryExprSyntax(contentBuilder: {
                for name in propertyNames {
                    DictionaryElementSyntax(key: StringLiteralExprSyntax(content: name.text), value: DeclReferenceExprSyntax(baseName: name))
                }
            })
            "var customMirror: Mirror { Mirror(self, children: \(kvp)) }"
        }
        return [extensionDecl]
    }
}
like image 80
Sweeper Avatar answered Jan 25 '26 06:01

Sweeper