【问题标题】:SwiftUI CoreData booleanSwiftUI CoreData 布尔值
【发布时间】:2021-10-17 05:58:18
【问题描述】:

我对使用 SwiftUI 的 CoreData 感到有些困惑,我只是在为 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)
        }
    }
}

【问题讨论】:

    标签: ios swift core-data swiftui


    【解决方案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
            }
        })
    }
    

    【讨论】:

    • 感谢您的澄清,我在 SwiftUI 中的 CoreData 上找不到太多信息。我将如何在真正的跑步中这样做?我目前也只有一个 bool 值集,如果我要添加更多,那很可能会导致问题。
    • @cole 我添加了代码,如果您的数据库为空,它将创建一个新的Item
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 2020-10-19
    • 2020-04-15
    • 2017-04-08
    相关资源
    最近更新 更多