如何在 SwiftData 中使用两个存储/配置

问题描述 投票:0回答:1

我正在尝试创建一个 SwiftData 应用程序,它有两个独立的 SQLite 数据存储 - 一个用于我将预先创建并与我的应用程序一起分发的数据,另一个用于用户在运行应用程序时将创建的数据 - 就像本文中所描述的那样 作者:保罗·哈德森。

当我创建并保存项目时,出现错误:

Failed to save after place creation: The model configuration used to open the store is incompatible with the one that was used to create the store.
为了测试,我有两个简单的模型:

@Model class Person: Identifiable { @Attribute(.unique) let id: UUID let name: String init(id: UUID = UUID(), name: String) { self.id = id self.name = name } } @Model class Place: Identifiable { @Attribute(.unique) let id: UUID let name: String init(id: UUID = UUID(), name: String) { self.id = id self.name = name } }
我初始化 SwiftData:

@main struct MultiStoreApp: App { var container: ModelContainer init() { let peopleStoreURL = URL.documentsDirectory.appending(path: "people.store") let placeStoreURL = URL.documentsDirectory.appending(path: "places.store") let peopleConfig = ModelConfiguration(schema: Schema([Person.self]), url: peopleStoreURL) let placesConfig = ModelConfiguration(schema: Schema([Place.self]), url: placeStoreURL) do { self.container = try ModelContainer(for: Person.self, Place.self, configurations: peopleConfig, placesConfig) } catch { fatalError("Failed to create model container: \(error.localizedDescription)") } } var body: some Scene { WindowGroup { ContentView() .modelContainer(container) } } }
然后我有一个简单的视图,显示所有地点和人员的列表,以及用于添加人员和地点的按钮。

struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query var people: [Person] @Query var places: [Place] var body: some View { NavigationStack { List { Section("People") { ForEach(people) { person in VStack(alignment: .leading) { Text(person.name) Text(person.id.uuidString) .font(.caption) } } } Section("Places") { ForEach(places) { place in VStack(alignment: .leading) { Text(place.name) Text(place.id.uuidString) .font(.caption) } } } } GroupBox { HStack { Button(action: { let person = Person(name: "Person \(people.count)") modelContext.insert(person) do { try modelContext.save() } catch { print("Failed to save after person creation: \(error.localizedDescription)") } }, label: { Text("Add Person") }) Spacer() Button(action: { let place = Place(name: "Place \(places.count)") modelContext.insert(place) do { try modelContext.save() } catch { print("Failed to save after place creation: \(error.localizedDescription)") } }, label: { Text("Add Place") }) } } .padding() } } }
当我在干净的模拟器上运行应用程序时,我可以添加一种类型的对象,但是一旦添加另一种类型的对象,我就开始收到错误。

我想做的事情可能吗?

swift swiftdata
1个回答
0
投票
你说得对!

但是您尝试使用两个单独的 SQLite 存储实现的方法在当前状态下不受

SwiftData 直接支持。

错误“用于打开商店的模型配置与用于创建商店的模型配置不兼容”清楚地表明了这一限制。

SwiftData 旨在与单个 ModelContainer 及其关联的存储一起使用。虽然您可以在该容器中定义多个模型,但它们都将共享相同的存储和架构。

为什么 SwiftData 不支持多个存储:

  • 数据一致性:在单个应用程序中管理多个商店需要复杂的机制来确保它们之间的数据完整性和一致性。

  • 性能:跨多个存储访问数据可能会带来显着的性能开销,特别是对于复杂的查询或关系。

  • 并发:处理对多个存储的并发访问需要仔细协调以避免数据损坏。

替代解决方案:

  • 使用单一商店:这是最直接的方法

  • 考虑核心数据:如果您确实需要多个存储并且具有更复杂的数据关系,核心数据在管理多个持久存储方面提供了更大的灵活性。

  • Realm 是一种流行的移动数据库,它提供了创建多个领域(商店)并管理它们之间关系的能力。但我从来没有尝试过。

© www.soinside.com 2019 - 2024. All rights reserved.