Preloading SwiftData Models with Relationships

Hey everyone! I posted this same issue in the Haching With Swift forums, but I hope it’s OK to post it here also…

Hey everyone! New iOS developer here… My first public app is going to be a trivia app with items divided into several categories. I’ve decided I’d like to use SwiftData to manage my 4-5 categories and 1500+ items.

In order to give me some practice in preparation for the development of the main app, I decided to try to create a simple app to create and manage the data store that will be used in the main app. I’ve spent days poring over tutorials, watching video, recreating all the apps decribed there. I’m currently trying to understand how to pre-populate some sample data into the data store. I’ve been successful in doing so with a single model or with multiple unrelated models. Where I’m struggling is to try to figure out if I can preload data into related models. I’ve seen a few examples discussing that very thing, but the relationships show in all those examples are between simple String properites. I’m trying to

@Model
class Category: Identifiable {
    
    @Attribute(.unique) let id: UUID = UUID()
    var name: String
    @Relationship(deleteRule: .cascade, inverse: \Trivia.category) var trivia: [Trivia]
 
    init(
        name: String,
        trivia: [Trivia] = [Trivia]()
    ) {
        self.name = name
        self.trivia = trivia
    }
}
@Model
class Trivia: Identifiable {
    @Attribute(.unique) let id: UUID = UUID()
    var question: String
    @Relationship(deleteRule: .cascade, inverse: \Answer.parent) var answers: [Answer]
    var category: Category?
    
    init(
        question: String,
        answers: [Answer],
        category: Category? = nil,
    ) {
        self.question = question
        self.answers = answers
        self.category = category
    }
}
@Model
class Answer {
    var parent: Trivia
    var text: String
    var isCorrect: Bool
    
    init(
        parent: Trivia,
        text: String,
        isCorrect: Bool
    ) {
        self.parent = parent
        self.text = text
        self.isCorrect = isCorrect
    }
}

I have created the sample data below that I’d like to preload. For now, I’m just focusing on the Category and Trivia models with Trivia.answers being an empty array. I’d eventually like to be able to add some data into that property as well, but I figured I needed to take it one step at a time. For the time being, my sample categories have not trivia property and my sample trivia items have not category property. I can preload the categories and the trivia items separately from each other, but I’m trying to understand how to establish the relationships during the preload process.

extension Category {
    static var starterCategories: [Category] {
        [
            Category(
                name: "Category 1"
            ),
            Category(
                name: "Category 2"
            ),
            Category(
                name: "Uncategorized"
            )
        ]
    }
}

extension Trivia {
    static var starterTrivia: [Trivia] {
        [
            Trivia(
                question: "A quien madruga",
                answers: [],
                // I'd like to be able to assign a category during the initial loading, but don't know how to do that.
            ),
            Trivia(
                question: "Question 2",
                answers: []
                // I'd like to be able to assign a category during the initial loading, but don't know how to do that.
            )
        ]
    }
}

Here’s the code for my app entry point. This was primarily taken from Stewart Lynch’s SwiftData video playlist although I have also reviewed the related HWS topics and others I have found also. The code belows gets my sample data loaded, but there’s no connection between the categories and trivia items.

import SwiftUI
import SwiftData

@main
struct TriviaManagerApp: App {
    let container: ModelContainer
    
    var body: some Scene {
        WindowGroup {
            HomeView()
        }
        .modelContainer(container)
    }
    
    init() {
        let schema = Schema([Category.self])
        print("Created schema variable")
        let config = ModelConfiguration("TriviaManager", schema: schema)
        print("Created model configuration")
        do {
            container = try ModelContainer(for: schema, configurations: config)
            print("Created container")
            
            var categoryFetchDescriptor = FetchDescriptor<Category>()
            categoryFetchDescriptor.fetchLimit = 1
            if try container.mainContext.fetch(categoryFetchDescriptor).count == 0 {
                Category.starterCategories.forEach {
                    container.mainContext.insert($0)
                }
            }

            var triviaFetchDescriptor = FetchDescriptor<Trivia>()
            triviaFetchDescriptor.fetchLimit = 1
            if try container.mainContext.fetch(triviaFetchDescriptor).count == 0 {
                Trivia.starterTrivia.forEach {
                    container.mainContext.insert($0)
                }
            }

        } catch {
            fatalError("Could not configure model container")
        }
        print(URL.applicationSupportDirectory.path(percentEncoded: false))
    }
}

Like I said, I’m new to all of this, so I may be missing something obvious, but over a weeks of multiple hours a day of tutorials and videos haven’t gotten me there yet… Any guidance would be appreciated!