如何定义可以接受不同实体的分段提取结果的通用 SwiftUI 视图

How to define a generic SwiftUI view that can accept sectioned fetch results for different entities

我需要定义一个通用的 SwiftUI 视图,它可以接受不同 CoreData 实体的分段提取结果,但我不确定如何定义通用视图。

在下面的示例中,我为 PatientDoctor 实体定义了两个分段的提取结果。我需要能够将它们传递给通用视图。

@SectionedFetchRequest(
    sectionIdentifier: \.sectionTitle,
    sortDescriptors: Patient.nameSortDescriptors(), animation: .default)
private var patients: SectionedFetchResults<String, Patient>

@SectionedFetchRequest(
    sectionIdentifier: \.sectionTitle,
    sortDescriptors: Doctor.nameSortDescriptors(), animation: .default)
private var doctors: SectionedFetchResults<String, Doctor>

GenericView(items: patients)
GenericView(items: doctors)

struct GenericView: View {
    let items: ?????
}

如果例如DoctorPatient符合协议Human,那么它可以如下

protocol Human {
    var name: String { get set }

    // other code here
}

class Doctor: NSManagedObject, Human {
    var name: String = ""

    // other code here
}

struct GenericView<T: NSManagedObject & Human>: View {
    let items: SectionedFetchResults<String, T>

    var body: some View {
    // other code here
    }
}

一种方法是不仅提供获取的结果,还提供用于结果中每个对象的视图。

下面的视图对于要显示的对象 Object 和要使用的视图 Content 是每个对象的通用视图。在这个例子中,我显示了所有对象的列表

struct GenericView<Object: NSManagedObject, Content: View>: View {
    let items: SectionedFetchResults<String, Object>
    let rowContent: (Object) -> Content

    init(items: SectionedFetchResults<String, Object>, rowContent: @escaping (Object) -> Content) {
        self.items = items
        self.rowContent = rowContent
    }
    
    var body: some View {
        List {
            ForEach(items) { section in
                Section(header: Text(section.id)) {
                    ForEach(section, id: \.objectID) { item in
                        rowContent(item)
                    }
                }
            }
        }
    }
}

然后你像这样为一个例子调用视图

GenericView(items: patients, rowContent: { patient in
    Text(patient.name)
})