I have a protocol Record : PersistentModel and my model conforms to this protocol.
protocol Record : PersistentModel
{
var title: String { get }
}
@Model
final class TestModel
{
let title: String
}
extension TestModel : Record {}
I also have genetic view that takes a Record.
struct GenericView<Element> : View
where Element : PersistentModel & Record
{
@Environment(\.modelContext)
private var modelContext
@Query
var elements: [Element]
var body: some View
{
List
{
ForEach(elements)
{
Text("element: \($0.title)") //works fine
}
Spacer()
}
}
}
This all works fine until I try to set a filter on the query in a generic way:
init(_ : Element.Type = Element.self, keyword: String)
//where Element = TestModel //works fine if where clause is present
{
let filter = #Predicate<Element> { element in
return element.title.contains(keyword) //does not work without the where clause
//return true //always works
}
self._elements = Query(filter: filter)
}
The preview keeps crashing and the message says it can't find TestModel.<computed ... (String)> on TestModel with PropertyMetadata(name: "title", keypath: \ TestModel.title,
Is this an issue that will always need to be worked around, something that will eventually be fixed/implemented in Swift or did I go wrong somewhere here?
I actually encountered the same exact problem. I find myself needing to make some fetching functions generic to avoid code duplication, but I end up with the same error
Couldn't find \MyType.<computed 0x0000000106269f70 (String)> on MyType with fields [...]
Now I don't have the generic type used in the FetchDescriptor. I kept all the generic reusable code I had before, but I also added the following to MyTypeProtocol
The draw back of this approach is that I need to duplicate the code in fetchDescriptorForCachedItem for every type conforming to MyTypeProtocol but I think is a good compromise given the fact that I manage to have a lot more reusable code in this way.