【问题标题】:CoreData UIKit SwiftUICoreData UIKit SwiftUI
【发布时间】:2021-10-09 08:49:00
【问题描述】:

我刚刚了解了 Swift 的 CoreData。我已经成功地让它在 SwiftUI 中运行,但无法使用相同的方法在基于 UIKit SwiftUI 的应用程序中运行。切换状态被保留并在纯 SwiftUI 应用程序中工作,所以我假设我可以在基于 UIKit 的 SwiftUI 应用程序中做类似的事情,但切换状态在 UIKit SwiftUI 应用程序中永远不会改变。

我在两个项目中使用相同的实体,属性名称,布尔值,并设置默认值。我的问题是我不能在基于UIKit 的 SwiftUI 应用中使用纯 SwiftUI 应用中的相同代码吗?

import CoreData

struct ContentView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.isOn, ascending: true)], animation: .default)
    private var items: FetchedResults<Item>
    
    var body: some View {
        VStack {
            Toggle("", isOn: Binding<Bool>(
                get: { items.first?.isOn ?? true},
                set: {
                    items.first?.isOn = $0
                    try? viewContext.save()
                    print("value: \($0)")
                }
            ))
            .labelsHidden()
            .frame(width: 100, height: 100, alignment: .center)
        }
    }
}

【问题讨论】:

  • 如果您同时发布 AppDelegate(来自 UIKit 版本)和 @main struct(来自纯 SwiftUI)的代码,以查看可能缺少的内容,也许它也有助于澄清初始化。
  • 也许您更愿意将它们称为:“SwiftUI 应用程序生命周期”和“带有 UIKit 应用程序生命周期的 SwiftUI”,这些可能是更常用的术语。

标签: swift core-data swiftui


【解决方案1】:

我不确定“基于 UIKit 的 SwiftUI 应用程序”是什么意思,但查看您的代码首先想到的是:

你有任何Item 对象吗?我没有看到你创建它的代码,如果没有 - 你的 setter 将什么也不做。

您可能忘记的另一件事是在您的SceneDelegate 中为您的根SwiftUI 视图设置.environment(\.managedObjectContext, context),或者在您使用UIHostingController 初始化它时设置.environment(\.managedObjectContext, context)

AppDelegate 应该有 persistentContainer: NSPersistentContainer,但如果你用 CoreData 创建了一个应用程序,你可能会拥有它。

【讨论】:

  • 带有 AppDelegate 的 SwiftUI,没有 AppDelegate 的纯 SwiftUI 工作正常。所以我看不出它为什么不起作用的区别。项目是通过 CoreData .xcdatamodeld 创建的
  • @cole .xcdatamodeld 只为一个项目创建一个类,我说的是初始化一个实例并将其保存到上下文中
  • 在 SwiftUI 应用程序中,我将其设置在我的 PersistenceController let newItem = Item(context: viewContext) newItem.isOn = true 中。但这可能是问题所在,我不确定在 AppDelegate 中的何处初始化它,或者?我只是注意到我没有设置它
  • @cole 不确定您在寻找什么,但您可以尝试在 AppDelegate 中进行操作,但不要忘记每次应用启动时都会调用它,因此您可能需要确保尚未创建,否则有一天您会在数据库中获得很多项目。
  • 你是对的,我在我的SceneDelegate 中添加了它并且它正在工作。只需在scene(_:willConnectTo:options:) 中添加let newItem = Item(context: context)newItem.isOn = true
猜你喜欢
  • 1970-01-01
  • 2020-10-19
  • 2021-09-06
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 2020-10-19
相关资源
最近更新 更多