1

我对CoreData使用 SwiftUI 感到有些困惑,我只是在为Toggle. 我设置了新创建的项目,PersistenceController但切换始终保持关闭。我没有太多使用经验CoreData,我之前关于 CoreData 的问题是不正确的,我被错误地告知了修复。

持久性控制器

static var preview: PersistenceController = {
    let result = PersistenceController(inMemory: true)
    let viewContext = result.container.viewContext
    for _ in 0..<10 {
        let newItem = Item(context: viewContext)
        newItem.bool = false
    }
    do {
        try viewContext.save()
    } catch {
        let nsError = error as NSError
        fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
    return result
}()

内容视图

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.bool, ascending: true)], animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        VStack {
            Toggle("", isOn: Binding<Bool>(
                get: { self.items.first?.bool ?? false },
                set: {
                    self.items.first?.bool = $0
                    try? viewContext.save()
                }
            ))
            .labelsHidden()
            .frame(width: 100, height: 100, alignment: .center)
        }
    }
}
4

1 回答 1

1
  1. 由于它来自变量的名称,preview仅用于预览,至少在新生成的项目中。因此,如果为空,则真正运行您的数据库
  2. 使用sortDescriptors您的项目列表按升序排序bool。这意味着一旦您将第一项设置bool为 true,它就会移动到列表的末尾,并且您正在bool从其他对象读取值

要在数据库为空时创建一个新Item的,您需要等待持久存储加载,获取项目并检查是否没有项目,在这种情况下 - 创建一个新的。替换PersistenceController init为以下内容:

init(inMemory: Bool = false) {
    container = NSPersistentContainer(name: "SwiftUICodeDataPlayground")
    if inMemory {
        container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
    }
    container.loadPersistentStores(completionHandler: { [self] (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
        if (try? container.viewContext.fetch(Item.fetchRequest()).isEmpty) != false {
            let newItem = Item(context: container.viewContext)
            newItem.bool = false
        }
    })
}
于 2021-08-14T08:39:38.943 回答