How do I take a ContextDescriptor and find if it conforms to a Protocol? #66
-
How do I take a ContextDescriptor and figure out if the context conforms to a particular protocol? I'm not sure this is possible and I'm still digging through the library. Ultimately, I want to find all types in the app that conforms to a specific protocol. Bonus points if I can then get access to a strongly typed
struct ExampleStructView: View { var body: some View { EmptyView() }}
// Step 1: Get all structs
let structs = types.compactMap { $0 as? StructDescriptor }
// Step 2: Check struct types if they conform to View
// ????
// Step 3: Profit
// Ideally these would be essentially the same lines
specialMethod(takesTypes: ExampleStructView.self)
specialMethod(takesTypes: someSpecializedVariable) If there are other routes to do this, let me know. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I have gotten closer but I get a cyclical reference that causes a EXC_BAD_ACCESS error when I run: let views = types
.compactMap { $0 as? StructDescriptor }
.compactMap { $0.accessor(.complete).metadata as? StructMetadata } // This causes an EXC_BAD_ACCESS error
.filter { $0.conformances.contains { $0.protocol.name == String(describing: View.self) }} I'm unsure how to determine when the accessor is safe to reference and when it will cause problems. Here's an instance of the debugging output:
|
Beta Was this translation helpful? Give feedback.
-
Writing one more answer as I finally got to where I needed to be. let views = types
.filter { !$0.flags.isGeneric }
.compactMap { $0 as? StructDescriptor }
.compactMap { $0.accessor(MetadataRequest(state: .abstract)) }
.compactMap { $0.metadata as? StructMetadata }
.filter { $0.conformances.contains { $0.protocol.name == String(describing: View.self) }}
.compactMap { $0.type } This has a big caveat that it does not pick up any views that are generic. For my purposes, that's ok for now, but this at least gets me a lot closer to my goals. UPDATE: types
.filter { !$0.flags.isGeneric }
.compactMap { $0 as? TypeContextDescriptor }
.compactMap { $0.accessor(MetadataRequest(state: .abstract)) }
.compactMap { $0.metadata as? TypeMetadata }
.filter { $0.conformances.contains { $0.protocol.name == String(describing: FlowRepresentable.self) }}
.reduce(into: [:]) { $0[$1.contextDescriptor.name] = $1.type } This creates a dictionary of type names and their types. |
Beta Was this translation helpful? Give feedback.
Writing one more answer as I finally got to where I needed to be.
This has a big caveat that it does not pick up any views that are generic. For my purposes, that's ok for now, but this at least gets me a lot closer to my goals.
UPDATE:
I found that this version is not restricted to Structs and makes finding conformance more flexible: