I am trying to setup data in the app during the first launch using SwiftData. If I try to add multiple items to a "1 to many" property, the app crashes.
I am stuck figuring how to make this work. Sample code below:
import SwiftUI
import SwiftData
class Persistance {
static var previewModelContainer: ModelContainer = {
let schema = Schema([
MyList.self,
MyItem.self,
])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
do {
let container=try ModelContainer(for: schema, configurations: [modelConfiguration])
//INITING LIST AND ITEMS
let list=MyList()
list.name="first list"
let item1=MyItem()
item1.name="item 1 name"
print("item1 created")
list.items.append(item1)
print("item1 added to list")
let item2=MyItem()
item2.name="item 2 name"
print("item2 created")
list.items.append(item2)
print("item2 added to list")
let actor=PersistanceActor(modelContainer: container)
Task {
await actor.insert(list)
print("list added to store")
}
return container
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
}
actor PersistanceActor: ModelActor {
let modelContainer: ModelContainer
let modelExecutor: any ModelExecutor
init(modelContainer: ModelContainer) {
self.modelContainer = modelContainer
let context = ModelContext(modelContainer)
modelExecutor = DefaultSerialModelExecutor(modelContext: context)
}
func save() {
do {
try modelContext.save()
}catch {
print("error inserting")
}
}
func insert<T:PersistentModel>(_ value:T) {
do {
modelContext.insert(value)
try modelContext.save()
}catch {
print("error inserting")
}
}
func delete<T:PersistentModel>(_ value:T) {
do {
modelContext.delete(value)
try modelContext.save()
}catch {
print("error inserting")
}
}
func get<T:PersistentModel>(_ descriptor:FetchDescriptor<T>)->[T]? {
var toReturn:[T]?
do {
toReturn=try modelContext.fetch(descriptor)
}catch {
print("error inserting")
}
return toReturn
}
}
@main
struct TestingSDApp: App {
var body: some Scene {
WindowGroup {
LaunchUIView()
}
.modelContainer(Persistance.previewModelContainer)
}
}
struct LaunchUIView: View {
@Environment(\.modelContext) private var context
@Query var list:[MyList]
var body: some View {
VStack {
ForEach(list, id: \.name) { item in
MyListItem(item: item)
}
}
}
}
struct MyListItem: View {
let item:MyList
var body: some View {
VStack {
ForEach(item.items, id: \.self) { item in
Text("\(item.name ?? "no item name")")
}
}
}
}
#Preview {
LaunchUIView()
.modelContainer(Persistance.previewModelContainer)
}
@Model
class MyList {
var name:String?=""
@Relationship(deleteRule: .cascade, inverse: \MyItem.myList)
var items:[MyItem]=[MyItem]()
init() {
}
}
@Model
class MyItem {
var name:String?=""
var myList:MyList?
init() {
}
}
if i comment out the list.items.append(item2) the code seems to work.
Any suggestions highly appreciated.