@DTS Engineer I encountered the same issue where there's a one-to-many relationship in Swift Data, and triggering an error while iterating through items in a subview.
I've created a "SwiftDataErrorDemo" project to facilitate reproducing the error. Since I can't upload the entire project, I'll describe it through specific steps:
- Create a SwiftUI project using Xcode 16.0 beta (16A5171c) and select SwiftData.
- Create Expense and Category models respectively.
@Model
final class Expense {
var acount: Double
var timestamp: Date
var category: Category?
init(acount: Double, timestamp: Date, category: Category) {
self.acount = acount
self.timestamp = timestamp
self.category = category
}
}
@Model
class Category {
var name: String
@Relationship(deleteRule: .cascade)
var expenses: [Expense]?
var timestamp: Date
init(name: String, timestamp: Date) {
self.name = name
self.timestamp = timestamp
}
}
- Add "insert test data code" in ContentView.
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var categories: [Category]
var body: some View {
NavigationSplitView {
List {
NavigationLink {
ExpensesListView()
} label: {
Text("Trigger BUG")
}
}
} detail: {
Text("Select an item")
}
.onAppear {
let category = Category(name: "🛍️", timestamp: .now)
modelContext.insert(category)
let newExpense = Expense(acount: Double.random(in: 20...30), timestamp: .now, category: category)
let newExpense2 = Expense(acount: Double.random(in: 20...30), timestamp: .now, category: category)
modelContext.insert(newExpense)
modelContext.insert(newExpense2)
}
}
}
- Fetch the Expense result set in ExpensesListView.
struct ExpensesListView: View {
@Query(filter: #Predicate<Expense> { $0.category?.name == "🛍️" })
private var expenses: [Expense]
var body: some View {
List {
if expenses.isEmpty {
ContentUnavailableView("No Data", systemImage: "magnifyingglass")
} else {
Text("Total: \(expenses.count)")
}
}
.onAppear {
print("Enter ExpensesListView")
}
}
}
Now, when you run SwiftDataErrorDemo using the iOS17 simulator, you can navigate to the ExpensesListView view normally. However, when running it with the iOS18 simulator, navigating to the ExpensesListView view will result in an error (or the interface will "freeze," with memory skyrocketing).