如何通过.onDelete方法可靠地从SwiftData容器中删除数据?
问题:SwiftData批量删除Report后数据回滚的异常情况
我是iOS开发新手,对SwiftData完全陌生,希望这不是个蠢问题。
我的SwiftData数据模型是一对多再到多的结构:一个Project包含多个Report,每个Report包含多个Item;Project的Report仅属于该Project,Report的Item仅属于该Report。
遇到的问题:将特定Project的Report列表传入List的ForEach视图,使用.onDelete方法删除Report时,经常出现删除后的Report在导航离开再返回、或关闭应用后重新出现的情况。这个问题不是每次都发生,且仅在删除2个及以上Report时出现。
相关代码
ActiveReports视图
import SwiftUI import SwiftData struct ActiveReports: View { @Environment(\.modelContext) private var context @State private var alertSaveError = false let projectReports: [Report] var body: some View { Group { List { ForEach(projectReports) { report in NavigationLink { ReportListView(report: report) } label: { HStack{ Text("\(report.scope)") Text("Version: \(report.version)") Spacer() Text("\(report.dateCreated.formatted(date: .abbreviated, time: .omitted))") } } } .onDelete(perform: deleteReport) } } .alert("Failed to Save", isPresented: $alertSaveError ){ Button("OK", role: .cancel) { } } } func deleteReport(_ indexSet: IndexSet) { for item in indexSet { let report = projectReports[item] context.delete(report) do{ try context.save() } catch { alertSaveError = true print("Error in saving") } } } }
Project模型
import Foundation import SwiftData @Model class Project { var name: String = "" var projectNumber: String = "" var scopes: [String] = [""] init(name: String, projectNumber: String, scopes: [String]) { self.name = name self.projectNumber = projectNumber self.scopes = scopes } @Relationship(deleteRule: .cascade) var reports: [Report]? = [] }
Report模型
import Foundation import SwiftData @Model class Report { var version: Int = 1 var scope: String = "" var dateCreated: Date = Date.now var issued: Bool = false init(version: Int, scope: String, issued: Bool) { self.version = version self.scope = scope self.issued = issued } // Setting the relationship back to parent Project @Relationship(inverse: \Project.reports) var project: Project? //Setting up the related punch items @Relationship(deleteRule: .cascade) var punchItems: [PunchItem]? }
已尝试的解决方案
- 使用
@Query宏获取Report列表,删除操作可靠,但会显示所有Project的Report;尝试过滤Query结果,无法实现动态过滤(传入Project名称仅获取其Report)。 - 强制保存模型容器,未出现保存失败,但问题依旧。
- 查阅资料发现类似行为是旧版本已知Bug(理论已修复),强制保存是临时方案,但对我无效。
我认为是自己的逻辑问题,但搞不懂为什么用@Query宏时删除可靠,传入数组时只有约50%的成功率。
编辑:把.onDelete方法改成ForEach项内的.swipeActions后,删除行为恢复正常,不确定是Bug还是自己理解不到位。
内容的提问来源于stack exchange,提问作者Dillonmk
相关产品推荐
相关产品推荐

