使用 FetchRequest 时如何在 PreviewProvider 中显示示例数据
How to show sample data in PreviewProvider when using FetchRequest
我有一个像这样的 SwiftUI 视图:
import SwiftUI
struct ReView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(
entity: Re.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Re.name, ascending: false)
]
) var entities: FetchedResults<Re>
var body: some View {
NavigationView {
List(entities, id: \.self) { entity in
Text(entity.name ?? "Unknown")
}
}
}
}
struct ReView_Previews: PreviewProvider {
static var previews: some View {
Group {
ReView()
.environment(\.managedObjectContext, PersistentCloudKitContainer.persistentContainer.viewContext)
}
}
}
如何在预览中显示一些样本数据?
我在为预览结构创建静态 moc 并根据需要向其中添加数据方面取得了一些成功。
像这样:
struct ReView_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
_ = Re(context: moc, mandatoryParam1: "foo" ...)
_ = Re(context: moc, mandatoryParam1: "bah" ...)
static var previews: some View {
Group {
ReView()
.environment(\.managedObjectContext, moc)
}
}
}
我对 SwiftUI 还处于早期阶段,所以几乎可以肯定有更优雅的实现方式。但是,从本质上讲,创建测试数据只是对模拟器上发生的序列进行编程以创建它,因为在实时模式下预览就是这样。
缺点是清除损坏的测试数据也需要一些编程工作。
祝你好运。
这里是适应的方法(早期在 中提出),用 Xcode 12 / iOS 14
测试
想法是将显式视图 + 模型与模型提供者(在本例中为云数据库)分开,因此可以设计和测试(预览)具有本地或动态构造的模拟模型(不涉及大量云连接)的视图
struct ReView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(
entity: Re.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Re.name, ascending: false)
]
) var entities: FetchedResults<Re>
var body: some View {
ReEntitiesView(entities: entities)
}
}
struct ReEntitiesView<Results:RandomAccessCollection>: View where Results.Element == Re {
let entities: Results
var body: some View {
NavigationView {
List(entities, id: \.self) { entity in
Text(entity.name ?? "Unknown")
}
}
}
}
struct ReView_Previews: PreviewProvider {
static let entity = NSManagedObjectModel.mergedModel(from: nil)?.entitiesByName["Re"]
static var previews: some View {
let object = Re(entity: entity!, insertInto: nil)
object.name = "Test Name"
return ReEntitiesView(entities: [object])
}
}
我今天仔细阅读了本指南,最后得到了一个令我满意的解决方案。
https://www.russellgordon.ca/tutorials/core-data-and-xcode-previews/
当您选择包含 CoreData 时,Xcode 现在使用其项目模板解决了部分问题。已创建 Persistence.swift 文件。如果你往里面看,有一个 static var preview
,你可以在其中制作一些提交给“预览上下文”的样本数据。
在您要预览的视图的 PreviewProvider 中,向覆盖 managedObjectContext 的视图实例添加修饰符,改为指向“预览上下文”。
struct ProductsList_Previews: PreviewProvider {
static var previews: some View {
ProductsList()
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
现在,当我的 ProductsList() 视图中的 FetchRequest 运行时,它会使用我在覆盖中使用的“预览上下文”。
在今天找到这篇文章之前,我已经学会了如何做所有这些事情。我 运行 之后遇到的障碍让我看到了这篇文章 - 如何为我的预览提供我的实体的单个示例。如果您也遇到困难,我会推荐这篇文章(在大多数情况下,这似乎是自然而然的下一步)。
我有一个像这样的 SwiftUI 视图:
import SwiftUI
struct ReView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(
entity: Re.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Re.name, ascending: false)
]
) var entities: FetchedResults<Re>
var body: some View {
NavigationView {
List(entities, id: \.self) { entity in
Text(entity.name ?? "Unknown")
}
}
}
}
struct ReView_Previews: PreviewProvider {
static var previews: some View {
Group {
ReView()
.environment(\.managedObjectContext, PersistentCloudKitContainer.persistentContainer.viewContext)
}
}
}
如何在预览中显示一些样本数据?
我在为预览结构创建静态 moc 并根据需要向其中添加数据方面取得了一些成功。
像这样:
struct ReView_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
_ = Re(context: moc, mandatoryParam1: "foo" ...)
_ = Re(context: moc, mandatoryParam1: "bah" ...)
static var previews: some View {
Group {
ReView()
.environment(\.managedObjectContext, moc)
}
}
}
我对 SwiftUI 还处于早期阶段,所以几乎可以肯定有更优雅的实现方式。但是,从本质上讲,创建测试数据只是对模拟器上发生的序列进行编程以创建它,因为在实时模式下预览就是这样。
缺点是清除损坏的测试数据也需要一些编程工作。
祝你好运。
这里是适应的方法(早期在 中提出),用 Xcode 12 / iOS 14
测试想法是将显式视图 + 模型与模型提供者(在本例中为云数据库)分开,因此可以设计和测试(预览)具有本地或动态构造的模拟模型(不涉及大量云连接)的视图
struct ReView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(
entity: Re.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Re.name, ascending: false)
]
) var entities: FetchedResults<Re>
var body: some View {
ReEntitiesView(entities: entities)
}
}
struct ReEntitiesView<Results:RandomAccessCollection>: View where Results.Element == Re {
let entities: Results
var body: some View {
NavigationView {
List(entities, id: \.self) { entity in
Text(entity.name ?? "Unknown")
}
}
}
}
struct ReView_Previews: PreviewProvider {
static let entity = NSManagedObjectModel.mergedModel(from: nil)?.entitiesByName["Re"]
static var previews: some View {
let object = Re(entity: entity!, insertInto: nil)
object.name = "Test Name"
return ReEntitiesView(entities: [object])
}
}
我今天仔细阅读了本指南,最后得到了一个令我满意的解决方案。
https://www.russellgordon.ca/tutorials/core-data-and-xcode-previews/
当您选择包含 CoreData 时,Xcode 现在使用其项目模板解决了部分问题。已创建 Persistence.swift 文件。如果你往里面看,有一个 static var preview
,你可以在其中制作一些提交给“预览上下文”的样本数据。
在您要预览的视图的 PreviewProvider 中,向覆盖 managedObjectContext 的视图实例添加修饰符,改为指向“预览上下文”。
struct ProductsList_Previews: PreviewProvider {
static var previews: some View {
ProductsList()
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
现在,当我的 ProductsList() 视图中的 FetchRequest 运行时,它会使用我在覆盖中使用的“预览上下文”。
在今天找到这篇文章之前,我已经学会了如何做所有这些事情。我 运行 之后遇到的障碍让我看到了这篇文章 - 如何为我的预览提供我的实体的单个示例。如果您也遇到困难,我会推荐这篇文章(在大多数情况下,这似乎是自然而然的下一步)。