我已经按照本教程学习了动态过滤器和CoreData: https://www.hackingwithswift.com/quick-start/ios-swiftui/dynamically-filtering-fetchrequest-with-swiftui
我有以下代码。 ContentView.swift :
import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@State var lastNameFilter = "A"
var body: some View {
VStack {
FilteredList(filter: lastNameFilter)
Button("Add Examples") {
let taylor = Singer(context: self.moc)
taylor.firstName = "Taylor"
taylor.lastName = "Swift"
let ed = Singer(context: self.moc)
ed.firstName = "Ed"
ed.lastName = "Sheeran"
let adele = Singer(context: self.moc)
adele.firstName = "Adele"
adele.lastName = "Adkins"
try? self.moc.save()
}
Button("Show A") {
self.lastNameFilter = "A"
}
Button("Show S") {
self.lastNameFilter = "S"
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
FilteredList.swift :
import CoreData
import SwiftUI
struct FilteredList: View {
var fetchRequest: FetchRequest<Singer>
var singers: FetchedResults<Singer> { fetchRequest.wrappedValue }
var body: some View {
List(singers, id: \.self) { singer in
Text("\(singer.wrappedFirstName) \(singer.wrappedLastName)")
}
}
init(filter: String) {
fetchRequest = FetchRequest<Singer>(entity: Singer.entity(), sortDescriptors: [], predicate: NSPredicate(format: "lastName BEGINSWITH %@", filter))
}
}
//struct FilteredList_Previews: PreviewProvider {
// static var previews: some View {
// }
//}
Singer + CoreDataClass.swift :
import Foundation
import CoreData
@objc(Singer)
public class Singer: NSManagedObject {
}
Singer + CoreDataProperties.swift :
import Foundation
import CoreData
extension Singer {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Singer> {
return NSFetchRequest<Singer>(entityName: "Singer")
}
@NSManaged public var firstName: String?
@NSManaged public var lastName: String?
var wrappedFirstName : String {
firstName ?? "Unknown"
}
var wrappedLastName : String {
lastName ?? "Unknown"
}
}
核心数据具有1个实体:Singer具有2个String属性:firstName和lastName。模块:当前产品模块。密码:手动/无。
当我尝试预览ContentView时,预览崩溃。当我打开崩溃日志文件并转到Debug Navigator时,我会看到以下错误:
调度队列:com.apple.main-thread(0)
在线:
FilteredList.swift :
var singers: FetchedResults<Singer> { fetchRequest.wrappedValue }
List(singers, id: \.self) { singer in
AppDelegate.swift :
class AppDelegate: UIResponder, UIApplicationDelegate {
可能是什么问题?包装的价值?代码有什么问题?
编辑: 这是我的Dropbox上的崩溃日志文件的链接: crash-logs
答案 0 :(得分:2)
帮助我的是将结构ContentView_Previews(...)更改为:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return ContentView().environment(\.managedObjectContext, context)
}
}
我也将struct FilteredList_Previews(...)更改为:
struct FilteredList_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return FilteredList(filter: "A").environment(\.managedObjectContext, context)
}
}
对@Gergely表示感谢,他在这里帮助我解决了类似的问题:https://stackoverflow.com/a/59629730/12315994
答案 1 :(得分:0)
尝试通过以下方式进行初始化:
@FetchRequest(fetchRequest: Singer.fetchRequest())
var singers: FetchedResults<Singer>
...
init(filter: String) {
_singers = FetchRequest<Singer>(entity: Singer.entity(),
sortDescriptors: [],
predicate: NSPredicate(format: "lastName BEGINSWITH %@", filter))
}
更新:我无法在本地重现崩溃,因此只能猜测...请参见上面的更新的初始化变量。
答案 2 :(得分:0)
我有同样的情况。提供从AppDelegate到预览的上下文,并向其中添加数据以解决崩溃问题:
struct FilteredList_Previews: PreviewProvider {
static var previews: some View {
let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let taylor = Singer(context: moc)
taylor.firstName = "Taylor"
taylor.lastName = "Swift"
return FilteredList().environment(\.managedObjectContext, moc)
}
}
不幸的是,该数据未显示我期望的确切数据(它显示了重复的条目)。但是对我来说,预览视图的设计已经足够了。 希望仍然有帮助。