1

I figured out how to code a reset button in my settings to delete all the data in the CoreData entity. However, the changes don't go into affect until you start the app. What code do I need to place into that function to make it immediately show all data deleted?

private func deleteAllData () {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
        let deleteRequest = NSBatchDeleteRequest( fetchRequest: fetchRequest)
        
        do{
            try viewContext.execute(deleteRequest)
            print("BATCH DELETE SUCCESS!")
        } catch let error as NSError {//handle error here
            print("BATCH DELETE FAILED")
        }
    }
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • 1
    You need to update whatever model is driving your view. This code remove the objects from Core Data, but it doesn't update your model, so the view doesn't update – Paulw11 Oct 10 '22 at 19:27
  • So if I have a SleepModel that has 12 variables as part of an Item entity, and then a ListViewModel that is where the coredata is setup….. what model do I update and how? I get what you’re saying, just don’t know how to implement it –  Oct 10 '22 at 19:50
  • 1
    It sounds like you need to re-fetch the data in your `ListViewModel` after you perform the delete (which will give you an empty data set) – Paulw11 Oct 10 '22 at 19:53
  • 1
    If you don’t have a large amount of data to delete then it might be better to do it the normal way to avoid the hustle of manually updating things. – Joakim Danielson Oct 10 '22 at 20:38
  • https://stackoverflow.com/questions/33533750/core-data-nsbatchdeleterequest-appears-to-leave-objects-in-context – Magnas Oct 11 '22 at 07:06

2 Answers2

1

Thank you to all. I found my exact answer I needed over at https://www.avanderlee.com/swift/nsbatchdeleterequest-core-data/. Not sure if we can post links to other sites but I don't want to take credit for how it was solved.

Here is the code I used to solve my issue and its correctly showing the deletion in live mode when you click the button (obviously the button calls the function when clicked):

private func deleteAllData () {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        deleteRequest.resultType = .resultTypeObjectIDs
        
        do {
            let result = try viewContext.execute(deleteRequest) as! NSBatchDeleteResult
            let changes: [AnyHashable: Any] = [
                NSDeletedObjectsKey: result.result as! [NSManagedObjectID]
            ]
            NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [viewContext])
        } catch let error as NSError {//handle error here
            print("BATCH DELETE FAILED")
        }
    }
0

Put this in your PersistenceController as the last line in init.

container.viewContext.automaticallyMergesChangesFromParent = true
malhal
  • 26,330
  • 7
  • 115
  • 133