使用 CoreData 预览 ContentView
Previewing ContentView with CoreData
当我尝试访问包含 CoreData 提取请求的 SwiftUI ContentView 时,预览崩溃了。想知道设置 @environment 以便预览可以访问核心数据堆栈的正确方法是什么。这在构建到模拟器但不适用于 PreviewProvider
时工作正常
import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(entity: ProgrammingLanguage.entity(), sortDescriptors: [
NSSortDescriptor(keyPath: \ProgrammingLanguage.name, ascending: true),
NSSortDescriptor(keyPath: \ProgrammingLanguage.creator, ascending: false)
]) var languages: FetchedResults<ProgrammingLanguage>
var body: some View {
NavigationView {
List {
ForEach(languages, id: \.self) { language in
Text("Language: \(language.name ?? "Anonymous")")
}
}
.navigationBarTitle("My Languages")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
当我尝试像这样将参数传递给 ContentView_Previews 中的 ContentView 时,出现以下编译器错误。
ContentView(managedObjectContext: managedObjectContext)
错误:实例成员 'managedObjectContext' 不能用于类型 'ContentView_Previews'
也许 SwiftUI 预览还不支持这个?或者有什么可以解决这个问题的吗?
我是 运行 Xcode 11 Beta 7.
归功于@ShadowDES - 在 Xcode Beta 7 的 Master/Detail 模板项目中有一个使用核心数据的预览:
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return ContentView().environment(\.managedObjectContext, context)
}
}
#endif
这在 Xcode Beta 5 中对我有用(我的 Beta 7 崩溃了)
接受的答案对我不起作用。
问题的实质是 Preview 似乎从它自己的(空的!)持久存储开始,因此您必须以某种方式用足够的对象填充该存储以使所有 Preview 正常工作。我创建了一个 class 函数,如果数据库为空,它会用示例对象填充我的数据库。此外,对于我模型中的每个实体,我创建了一个静态 属性,其中 return 这些示例对象之一作为参数传递,根据需要,用于正在预览的特定视图。
如果预览使用大量托管对象,这会简化预览代码:
struct StringAttributeView_Previews: PreviewProvider {
static var previews: some View {
Preview.database()
return NavigationView {
StringAttributeView(attribute: Preview.attribute)
}
}
}
这是我的预览 class 的编辑示例。显然,它特定于我的 DataModel class,并且必须针对您独特的数据模型进行定制,但它应该让您了解需要什么。
class Preview {
//MARK: - Populate Preview's Core Data Database
class func database() {
if DataModel.isDatabaseEmpty() {
McDocument.loadSampleData()
}
}
//MARK: - For Previews
class var attribute:
Attribute { get { return DataModel.allObjects(for: "Attribute").first as! Attribute } }
}
当我尝试访问包含 CoreData 提取请求的 SwiftUI ContentView 时,预览崩溃了。想知道设置 @environment 以便预览可以访问核心数据堆栈的正确方法是什么。这在构建到模拟器但不适用于 PreviewProvider
时工作正常import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(entity: ProgrammingLanguage.entity(), sortDescriptors: [
NSSortDescriptor(keyPath: \ProgrammingLanguage.name, ascending: true),
NSSortDescriptor(keyPath: \ProgrammingLanguage.creator, ascending: false)
]) var languages: FetchedResults<ProgrammingLanguage>
var body: some View {
NavigationView {
List {
ForEach(languages, id: \.self) { language in
Text("Language: \(language.name ?? "Anonymous")")
}
}
.navigationBarTitle("My Languages")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
当我尝试像这样将参数传递给 ContentView_Previews 中的 ContentView 时,出现以下编译器错误。
ContentView(managedObjectContext: managedObjectContext)
错误:实例成员 'managedObjectContext' 不能用于类型 'ContentView_Previews'
也许 SwiftUI 预览还不支持这个?或者有什么可以解决这个问题的吗?
我是 运行 Xcode 11 Beta 7.
归功于@ShadowDES - 在 Xcode Beta 7 的 Master/Detail 模板项目中有一个使用核心数据的预览:
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return ContentView().environment(\.managedObjectContext, context)
}
}
#endif
这在 Xcode Beta 5 中对我有用(我的 Beta 7 崩溃了)
接受的答案对我不起作用。
问题的实质是 Preview 似乎从它自己的(空的!)持久存储开始,因此您必须以某种方式用足够的对象填充该存储以使所有 Preview 正常工作。我创建了一个 class 函数,如果数据库为空,它会用示例对象填充我的数据库。此外,对于我模型中的每个实体,我创建了一个静态 属性,其中 return 这些示例对象之一作为参数传递,根据需要,用于正在预览的特定视图。
如果预览使用大量托管对象,这会简化预览代码:
struct StringAttributeView_Previews: PreviewProvider {
static var previews: some View {
Preview.database()
return NavigationView {
StringAttributeView(attribute: Preview.attribute)
}
}
}
这是我的预览 class 的编辑示例。显然,它特定于我的 DataModel class,并且必须针对您独特的数据模型进行定制,但它应该让您了解需要什么。
class Preview {
//MARK: - Populate Preview's Core Data Database
class func database() {
if DataModel.isDatabaseEmpty() {
McDocument.loadSampleData()
}
}
//MARK: - For Previews
class var attribute:
Attribute { get { return DataModel.allObjects(for: "Attribute").first as! Attribute } }
}