I'm looking to create a protocol upon View to group views that can be constructed from some specific data struct (MyData)
protocol EncodableView: View {
  /// Returns true if this view type can be decoded from data
  static func canDecode(from data: MyData) -> Bool
  /// Constructs a view from the given data
  init(from data: MyData) throws
}
I want to use this protocol in a view to route to different views based on their ability to decode MyData:
struct Example: EncodableView {
  // ... implements EncodableView
}
struct ContentView: View {
  private var encodableViews: [any EncodableView.Type] = [ 
    ExampleView.self,
    // ... others
  ]
  private func navigationDestination(for data: MyData) -> some View {
    for (type in encodableViews) {
      // Compile complains: Type 'any EncodableView' cannot conform to 'View'
      if (type.canDecode(data)) { 
        return type.init(from: data)
      }
    }
    return EmptyView()
  }
  var body: some View {
    NavigationStack {
      VStack {
        // ...
      }
      .navigationDestination(for: MyData.self) { data in
         navigationDestination(for: data)
      }
    }
  }
}
However, I'm having trouble finding the right combination of some View, any View, AnyView and generics to achieve this.
I've marked the spot in my code snippet above where the compile complains: Type 'any EncodableView' cannot conform to 'View'
                        
One Solution but not ideal because while checking the
suffixis fast you wouldn't want to check every time the view is redrawn.Then you can use it something like
but like I mentioned above the decision will be happening multiple times, views shouldn't be deciding.
You could decide before and then tell the
Viewwhat it is and what to show.And use it in your
navigationDestinationBut you could use generics too just be concrete when you get to the
ViewAnd in the
navigationDestinationThe more decisions and processing your put on a
View/main thread/ main actor the slower and more sluggish your app will be.