为 SwiftUI 中的预览传递核心数据 FetchedResults<T>

And*_*drw 5 core-data swiftui

我有一个父视图,它执行 a@FetchRequest并将 传递FetchedResults<T>给子视图。一切正常,子视图能够通过FetchedResults. 但是,我不知道如何设置数据以便孩子的Preview结构能够工作。在Previewstruct 中设置一些常量数据以便我可以实例化子视图并传入的正确方法是FetchedResults<T>什么?

use*_*957 8

在预生成的 PersistenceController 结构(在“Persistence.swift”文件内)中使用预览PersistenceController。

因此,如果您从核心数据“项目”实体传递一个项目:

struct ContentView: View {
...
private var items: FetchedResults<Item>
..
ForEach(items) { item in
DetailView(item: item)
}
..
Run Code Online (Sandbox Code Playgroud)

在详细信息视图中,如下所示:


struct DetailView: View {
    var item: FetchedResults<Item>.Element
    
    var body: some View {
        Text("Items text = \(item.text ?? "")")
    }
}

struct Detail_Previews: PreviewProvider {

    static var previews: some View {
        let viewContext = PersistenceController.preview.container.viewContext
        let previewItem = Item(context: viewContext)
        previewItem.text = "Text4preview"
        
        return Detail(item: previewItem)
    }
}
Run Code Online (Sandbox Code Playgroud)


Asp*_*eri 6

就像FetchedResults<T>aRandomAccessCollection和 swift 数组也是 a RandomAccessCollection,这里是可能的解决方案。

使用 Xcode 11.4 / iOS 13.4 测试

struct ContentView: View {
    @Environment(\.managedObjectContext) var context
    @FetchRequest(entity: Person.entity(), sortDescriptors: [])
        var result: FetchedResults<Person>

    var body: some View {
        VStack(alignment: .leading) {
            Text("Persons").font(.title)
            PersonsView(results: result) // FetchedResults<Person> is a collection
        }
    }
}

// generalize PersonsView to depend just on collection
struct PersonsView<Results:RandomAccessCollection>: View where Results.Element == Person {
    let results: Results
    var body: some View {
        ForEach(results, id: \.self) { person in
            Text("Name: \(person.name ?? "<unknown>")")
        }
    }
}

struct ChildView_Previews: PreviewProvider {
    static var previews: some View {
        PersonsView(results: [Person()]) // << use regular array to test
    }
}
Run Code Online (Sandbox Code Playgroud)

更新: Xcode 12 / iSO 14 的固定和测试部分(由于上述 PreviewProvider 崩溃)

看起来实体现在应该被明确地读取和指定:

struct ChildView_Previews: PreviewProvider {
    static let entity = NSManagedObjectModel.mergedModel(from: nil)?.entitiesByName["Person"]

    static var previews: some View {
        let person = Person(entity: entity!, insertInto: nil)
        person.name = "Test Name"

        return PersonsView(results: [person])
    }
}
Run Code Online (Sandbox Code Playgroud)