In my application I have defined the following Protocol, which is intended to make all SwiftData models that inherit the NameFilter Protocol to define var name: String exits.
@Model class Session: NameFilter
{
var name: String
var x: ….
var y: …
}
import Foundation
protocol NameFilter{
associatedtype String
var name: String {get set}
}
My Session DataModel class
import Foundation
import SwiftData
@Model final class WCSession: NameFilter {
var id: String = UUID().uuidString
var name: String = "" //i.e. Spring 2024
var number: String = "" // 133
var startDate: Date = Date.distantPast // Jun 1
var isCurrent: Bool = false // True
init(name: String, number: String, startDate: Date, isCurrent: Bool) {
self.name = name
self.number = number
self.startDate = startDate
self.isCurrent = isCurrent
}
}
My Generic View
import SwiftUI
import Observation
import SwiftData
struct NavigationStackToolbar<T>: View {
// Bring in my Observable ApplicationData
@Environment(ApplicationData.self) var appData
// Bring in my modelContext defined as dbContext
@Environment(.modelContext) var dbContext
// Setup my DataQuery of type T
@Query var listItems: [T]
// passed in dataModel from Caller
@State var dataModel: String
// Our Search Query
@State var searchQuery = ""
// Define NameFilter Protocols
@State var name: String = ""
// Setup filter -> Pass in Query Filter or Build here with helpers
var filteredItems: [T] {
if searchQuery.isEmpty {
return listItems
}
// Error on line below : Generic parameter 'ElementOfResult' could not be inferred
// ***********************************************VVVVVVVV *********
let filteredItems = listItems.compactMap { item in
let nameContainsQuery = (item.name as String).range(of: searchQuery, options: .caseInsensitive) != nil
return(nameContainsQuery) ? listItems : nil
}
return filteredItems
}
var body: some View {
NavigationStack(path: Bindable(appData).viewPath) {
List(filteredItems) { item in
HStack {
CellSession(item: item)
}
}
}
}
}
I realize that I need to help the compile know the type by type casting the value.
I have tried the following but can make it work
let nameContainsQuery = (item.name as String).range(of: searchQuery, options: .caseInsensitive) != nil
//. item.name is indicated with the error --> X Value of type 'T' has no member 'name'
The idea in this design is to simplify the view so that is is broken down into parts that can be quickly type checked. I get error stating Compiler ran out of time type checking view. Please break it down into small components …
I want to create a prototype Model that has a generic Filter on the Model Properity Name which is of type string. Any SwiftData Model that inherits NameFilter would be eligable to filter that view by Name Generically