Search code examples
swiftuiios17swiftdata

Can't Convert SwiftData Model Data to expected argument type NSManagedObject


I have been in the process recently converting my app CoreData code to SwiftData. I have the read and write operations working but ran into a problem with onDelete. I'm guessing that onDelete doesn't like one or more of my parameters in the model TravelEntries class.

Cannot convert value of type 'TravelEntries' to expected argument type 'NSManagedObject'

I searched around the internet but did not find anything on the subject NSManaged Object and SwiftData. I texted out the SwiftData delete and noted that all the data available in deleteEntry was correct, singleOffset had a value of 2 (Int), being the third entry in the list. So what am I missing?

@Model class TravelEntries {

    var id: UUID
    var entryDate: Date
    var entryTimeZone: String
    var entryLat: Double
    var entryLong: Double

    var entryCatNum: Int64
    var entryCatName: String
    var entryCode: String
    var entryCurCountry: String
    var entryDsc: String
    var entryPayType: Int64
    var entryMoney: Double
    var entryRate: Double

    var entryLocCity: String
    var entryLocState: String
    var entryLocCountry: String


    init(id: UUID = UUID(), entryDate: Date = Date(), entryTimeZone: String = "", entryLat: Double = 0.0, entryLong: Double = 0.0, entryCatNum: Int64 = 0, entryCatName: String = "", entryCode: String = "", entryCurCountry: String = "", entryDsc: String = "", entryPayType: Int64 = 0, entryMoney: Double = 0.0, entryRate: Double = 0.0, entryLocCity: String = "", entryLocState: String = "", entryLocCountry: String = "") {
        self.id = id
        self.entryDate = entryDate
        self.entryTimeZone = entryTimeZone
        self.entryLat = entryLat
        self.entryLong = entryLong
        self.entryCatNum = entryCatNum
        self.entryCatName = entryCatName
        self.entryCode = entryCode
        self.entryCurCountry = entryCurCountry
        self.entryDsc = entryDsc
        self.entryPayType = entryPayType
        self.entryMoney = entryMoney
        self.entryRate = entryRate
        self.entryLocCity = entryLocCity
        self.entryLocState = entryLocState
        self.entryLocCountry = entryLocCountry
    }
}
struct HistoryView: View {

    @Environment(\.managedObjectContext) var viewContext
    @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: entryDate)
                    }
                    .onDelete(perform: deleteEntry)
                }
            }
        }
    }

    func deleteEntry(at offsets: IndexSet) {
        offsets.forEach { singleOffset in

            // gather entry info necessary to update totals
            let localCur = travelEntries[singleOffset].entryMoney
            let xchRate = travelEntries[singleOffset].entryRate
            let entryCat = Int( travelEntries[singleOffset].entryCatNum)
            let entryDate = travelEntries[singleOffset].entryDate

            viewContext.delete(travelEntries[singleOffset]) // <-- error here

            // ... update system totals
        }
    }
}


Solution

  • Instead of

    @Environment(\.managedObjectContext) var viewContext
    

    You need to use

    @Environment(\.modelContext) var viewContext
    

    Make sure you are also using

    .modelContainer(for: TravelEntries.self)
    

    At the top level of the app instead of

    .environment(\.managedObjectContext, some Context)
    

    Apple has a nice article https://developer.apple.com/documentation/coredata/adopting_swiftdata_for_a_core_data_app

    managedObjectContext is for a CoreData stack not a SwiftData stack.