SwiftData迁移报错:TravelEntries无法转为NSManagedObject
解决SwiftData迁移中onDelete的类型转换错误:无法将'TravelEntries'转换为'NSManagedObject'
问题原因
你当前代码混用了CoreData与SwiftData的API:@Environment(\.managedObjectContext)是CoreData专属的上下文对象,而SwiftData中被@Model修饰的TravelEntries类并不继承自NSManagedObject,因此调用viewContext.delete()时会触发类型不匹配的错误。
解决方案
将CoreData上下文替换为SwiftData专用的ModelContext,统一使用SwiftData的API执行删除操作:
替换环境上下文类型
把@Environment(\.managedObjectContext)替换为@Environment(\.modelContext),这是SwiftData专门用于操作@Model类实例的上下文对象。修改删除方法调用
在deleteEntry方法中,用modelContext.delete()替代原有的viewContext.delete(),ModelContext支持直接接收@Model修饰的对象实例。(可选)手动保存上下文
SwiftData默认会自动保存上下文,但如果需要确保删除操作立即持久化,可以在删除后调用save()方法。
修改后的完整代码
struct HistoryView: View { @Environment(\.modelContext) var modelContext // 替换为SwiftData上下文 @Query(sort: \TravelEntries.entryDate) var travelEntries: [TravelEntries] var body: some View { GeometryReader { g in VStack { List { ForEach(travelEntries) { item in showRow(g: g, item: item, entryDate: item.entryDate) // 修正原代码中entryDate的引用问题 } .onDelete(perform: deleteEntry) } } } } func deleteEntry(at offsets: IndexSet) { offsets.forEach { singleOffset in // 收集更新总计所需的条目信息 let localCur = travelEntries[singleOffset].entryMoney let xchRate = travelEntries[singleOffset].entryRate let entryCat = Int(travelEntries[singleOffset].entryCatNum) let entryDate = travelEntries[singleOffset].entryDate modelContext.delete(travelEntries[singleOffset]) // 使用SwiftData上下文执行删除 // (可选)保存上下文确保修改持久化 do { try modelContext.save() } catch { print("删除条目时保存失败:\(error.localizedDescription)") } // ... 更新系统总计 } } }
额外说明
迁移到SwiftData后,应避免同时使用CoreData的API(如NSManagedObjectContext),保持API一致性可避免此类类型兼容问题。
内容的提问来源于stack exchange,提问作者Galen Smith
相关产品推荐
相关产品推荐

